Understanding Objective-c Runtime (v) protocols and classifications

Source: Internet
Author: User
Tags list of attributes



The classification in objective-c allows us to augment it by adding a method to a class (but we cannot add new instance variables through category), and we do not need to access the code in the class.



The protocol in OBJECTIVE-C is a ubiquitous interface definition, in which an interface is defined in a class by @protocol and an interface is implemented in another class, and this interface definition becomes "delegation" mode, @ protocol declares a method that can be implemented by any other method class, and the protocol simply defines an interface and is implemented by other classes.



Let's take a look at runtime's support for classification and protocols.



Underlying data type



Category



The category is a pointer to a struct that points to the classification, which is defined as follows:


typedef struct objc_category * Category;
 
struct objc_category {
     char * category_name OBJC2_UNAVAILABLE; // category name
     char * class_name OBJC2_UNAVAILABLE; // class name to which the category belongs
     struct objc_method_list * instance_methods OBJC2_UNAVAILABLE; // list of instance methods
     struct objc_method_list * class_methods OBJC2_UNAVAILABLE; // class method list
     struct objc_protocol_list * protocols OBJC2_UNAVAILABLE; // list of protocols implemented by classification
}


This structure mainly contains the instance and class methods of the classification definition, where the Instance_methods list is a subset of the method list in Objc_class, and the Class_methods list is a subset of the meta-class method list.



Protocol



Protocol is defined as follows:


typedef struct OBJC_OBJECT Protocol;


As we can see, protocol is actually an object structure.



Operation function



Runtime does not provide an operation function for classification in the <objc/runtime.h> header file. Because the information in these classifications is contained in the Objc_class, we can get the classified information by the operation function for Objc_class. As shown in the following example:


@interface RuntimeCategoryClass: NSObject
-(void) method1;
@end
 
@interface RuntimeCategoryClass (Category)
-(void) method2;
@end
 
@implementation RuntimeCategoryClass
 
-(void) method1 {
 
}
 
@end
 
@implementation RuntimeCategoryClass (Category)
 
-(void) method2 {
 
}
 
@end
 
#pragma mark-
 
NSLog (@ "Tests if the method list in objc_class contains methods in the category");
unsigned int outCount = 0;
Method * methodList = class_copyMethodList (RuntimeCategoryClass.class, & outCount);
 
for (int i = 0; i <outCount; i ++) {
     Method method = methodList [i];
 
     const char * name = sel_getName (method_getName (method));
 
     NSLog (@ "RuntimeCategoryClass ‘s method:% s", name);
 
     if (strcmp (name, sel_getName (@selector (method2)))) {
         NSLog (@ "Classification method method2 is in the method list of objc_class");
     }
}


Its output is:


2015-06-18 10: 36: 39.213 [561: 151847] Test if the method list in objc_class contains methods in the classification
2015-06-18 10: 36: 39.215 [561: 151847] RuntimeCategoryClass ‘s method: method2
2015-06-18 10: 36: 39.215 [561: 151847] RuntimeCategoryClass ‘s method: method1
2015-06-18 10: 36: 39.215 [561: 151847] The classification method method2 is in the method list of objc_class


For Protocol,runtime, a series of functions are provided to manipulate these functions, including:


// return the specified protocol
Protocol * objc_getProtocol (const char * name);
 
// Get an array of all protocols known at runtime
Protocol ** objc_copyProtocolList (unsigned int * outCount);
 
// create a new protocol instance
Protocol * objc_allocateProtocol (const char * name);
 
// Register the newly created protocol in the runtime
void objc_registerProtocol (Protocol * proto);
 
// Add a method to the protocol
void protocol_addMethodDescription (Protocol * proto, SEL name, const char * types, BOOL isRequiredMethod, BOOL isInstanceMethod);
 
// add a registered protocol to the protocol
void protocol_addProtocol (Protocol * proto, Protocol * addition);
 
// Add attributes to the protocol
void protocol_addProperty (Protocol * proto, const char * name, const objc_property_attribute_t * attributes, unsigned int attributeCount, BOOL isRequiredProperty, BOOL isInstanceProperty);
 
// return the protocol name
const char * protocol_getName (Protocol * p);
 
// test if two protocols are equal
BOOL protocol_isEqual (Protocol * proto, Protocol * other);
 
// Get the method description array of the method with the specified conditions in the protocol
struct objc_method_description * protocol_copyMethodDescriptionList (Protocol * p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int * outCount);
 
// Get the method description of the specified method in the protocol
struct objc_method_description protocol_getMethodDescription (Protocol * p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);
 
// Get the list of attributes in the protocol
objc_property_t * protocol_copyPropertyList (Protocol * proto, unsigned int * outCount);
 
// Get the specified attributes of the protocol
objc_property_t protocol_getProperty (Protocol * proto, const char * name, BOOL isRequiredProperty, BOOL isInstanceProperty);
 
// Get the protocol used by the protocol
Protocol ** protocol_copyProtocolList (Protocol * proto, unsigned int * outCount);
 
// see if the protocol uses another protocol
BOOL protocol_conformsToProtocol (Protocol * proto, Protocol * other); 


Objc_getprotocol function, it is important to note that if you simply declare a protocol and do not implement it in any class, the function returns nil.



Objc_copyprotocollist function, the obtained array needs to use free to release



Objc_allocateprotocol function, returns nil if a protocol with the same name already exists



The Objc_registerprotocol function, after creating a new protocol, must call the function to register the new protocol at run time. The agreement can be used after registration, but no further modification, that is, after registration can no longer add a method or protocol to the Agreement



It should be emphasized that once the protocol is registered, it can no longer be modified, that is, it is no longer possible to add methods to the protocol by calling Protocol_addmethoddescription, Protocol_addprotocol, and Protocol_addproperty.



Summary



Runtime does not provide too many functions to handle the classification. For the protocol, we can create the protocol dynamically and add methods, properties, and inherited protocols to it, and obtain the information dynamically at run time.






Understanding Objective-c Runtime (v) protocols and classifications


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.