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.
In this chapter, we look at runtime's support for classification and protocols.
Basic 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:
2014-11-08 10: 36: 39.213 [561: 151847] Test if the method list in objc_class contains methods in the classification
2014-11-08 10: 36: 39.215 [561: 151847] RuntimeCategoryClass ‘s method: method2
2014-11-08 10: 36: 39.215 [561: 151847] RuntimeCategoryClass ‘s method: method1
2014-11-08 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.
Note: If there is a mistake, please correct me, welcome to add QQ Friends: 1318202110 (South peak son)
Reference
- Objective-c Runtime Reference
http://southpeak.github.io/blog/2014/11/08/objective-c-runtime-yun-xing-shi-zhi-wu-:xie-yi-yu-fen-lei/
OBJECTIVE-C Runtime Five: protocols and classifications