struct objc_class { Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; constchar *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif
} OBJC2_UNAVAILABLE; /* Use `Class` instead of `struct objc_class *` */
__OBJC2__
If you are running 10.5 or later, or any version of iOS, your computer is running Objective-C 2. If you are writing code which you want to work on systems before this, you can check for the OBJC2 macro, which will be defined only for Objective-C 2 and later systems.
/* OBJC2_UNAVAILABLE: unavailable in objc 2.0, deprecated in Leopard */ /*主要是为了兼容以前的OC版本,目前条件下,可忽略 */ #if !defined(OBJC2_UNAVAILABLE) # if __OBJC2__ # define OBJC2_UNAVAILABLE UNAVAILABLE_ATTRIBUTE # else /* plain C code also falls here, but this is close enough */ # define OBJC2_UNAVAILABLE \ __OSX_DEPRECATED(10.5, 10.5, "not available in __OBJC2__") \ __IOS_DEPRECATED(2.0, 2.0, "not available in __OBJC2__") \ __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE # endif #endif
/** * Returns the superclass of a class. * * @param cls A class object. * * @return The superclass of the class, or \c Nil if * \e cls is a root class, or \c Nil if \e cls is \c Nil. * * @note You should usually use \c NSObject's \c superclass method instead of this function. */ OBJC_EXPORT Class class_getSuperclass(Class cls) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
获取version
1 2 3 4 5 6 7 8 9 10 11 12
/** * Returns the version number of a class definition. * * @param cls A pointer to a \c Class data structure. Pass * the class definition for which you wish to obtain the version. * * @return An integer indicating the version number of the class definition. * * @see class_setVersion */ OBJC_EXPORT int class_getVersion(Class cls) OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
获取name
1 2 3 4 5 6 7 8 9
/** * Returns the name of a class. * * @param cls A class object. * * @return The name of the class, or the empty string if \e cls is \c Nil. */ OBJC_EXPORT constchar *class_getName(Class cls) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
获取instance_size
1 2 3 4 5 6 7 8 9
/** * Returns the size of instances of a class. * * @param cls A class object. * * @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil. */ OBJC_EXPORT size_t class_getInstanceSize(Class cls) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
/** * Describes the instance variables declared by a class. * * @param cls The class to inspect. * @param outCount On return, contains the length of the returned array. * If outCount is NULL, the length is not returned. * * @return An array of pointers of type Ivar describing the instance variables declared by the class. * Any instance variables declared by superclasses are not included. The array contains *outCount * pointers followed by a NULL terminator. You must free the array with free(). * * If the class declares no instance variables, or cls is Nil, NULL is returned and *outCount is 0. */ OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsignedint *outCount) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
获得methodLists
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/** * Describes the instance methods implemented by a class. * * @param cls The class you want to inspect. * @param outCount On return, contains the length of the returned array. * If outCount is NULL, the length is not returned. * * @return An array of pointers of type Method describing the instance methods * implemented by the class—any instance methods implemented by superclasses are not included. * The array contains *outCount pointers followed by a NULL terminator. You must free the array with free(). * * If cls implements no instance methods, or cls is Nil, returns NULL and *outCount is 0. * * @note To get the class methods of a class, use \c class_copyMethodList(object_getClass(cls), &count). * @note To get the implementations of methods that may be implemented by superclasses, * use \c class_getInstanceMethod or \c class_getClassMethod. */ OBJC_EXPORT Method *class_copyMethodList(Class cls, unsignedint *outCount) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
获得protocols
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/** * Describes the protocols adopted by a class. * * @param cls The class you want to inspect. * @param outCount On return, contains the length of the returned array. * If outCount is NULL, the length is not returned. * * @return An array of pointers of type Protocol* describing the protocols adopted * by the class. Any protocols adopted by superclasses or other protocols are not included. * The array contains *outCount pointers followed by a NULL terminator. You must free the array with free(). * * If cls adopts no protocols, or cls is Nil, returns NULL and *outCount is 0. */ OBJC_EXPORT Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, unsignedint *outCount) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
#import "objc-private.h" #import <Foundation/Foundation.h> int main(int argc, constchar * argv[]) { @autoreleasepool { Class cls = [NSObjectclass]; unsignedint count = 0; Ivar *list = class_copyIvarList(cls, &count); for (unsignedint i = 0; i < count; ++i) { Ivar ity = list[i]; constchar *iname = ivar_getName(ity); NSLog(@"%@\n",[NSString stringWithUTF8String:iname]); } free(list); objc_property_t *list2 = class_copyPropertyList(cls, &count); for (unsignedint i = 0; i < count; ++i) { objc_property_t ity = list2[i]; constchar *iname = property_getName(ity); NSLog(@"%@\n",[NSString stringWithUTF8String:iname]); } free(list2); Method *methods = class_copyMethodList(cls, &count); for (unsignedint i = 0; i < count; i++) { Method method = methods[i]; printf("\t'%s'|'%s' of encoding '%s'\n", class_getName(cls), sel_getName(method_getName(method)), method_getTypeEncoding(method)); } free(methods); Protocol * __unsafe_unretained * protocols = class_copyProtocolList(cls, &count); Protocol * protocol; for (unsignedint i = 0; i < count; i++) { protocol = protocols[i]; NSLog(@"protocol name: %s", protocol_getName(protocol)); } } return0; }
输出效果
获得cache
为已有类添加ivar,property,method,protocol
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Adds a new instance variable to a class. * * @return YES if the instance variable was added successfully, otherwise NO * (for example, the class already contains an instance variable with that name). * * @note This function may only be called after objc_allocateClassPair and before objc_registerClassPair. 需要在obj_allocateClassPair与objc_registerClassPair之间调用 * Adding an instance variable to an existing class is not supported. 不支持为已有的类添加实例变量 * @note The class must not be a metaclass. Adding an instance variable to a metaclass is not supported. 不支持为元类添加实例变量 * @note The instance variable's minimum alignment in bytes is 1<<align. The minimum alignment of an instance * variable depends on the ivar's type and the machine architecture. * For variables of any pointer type, pass log2(sizeof(pointer_type)). */ OBJC_EXPORT BOOL class_addIvar(Class cls, constchar *name, size_t size, uint8_t alignment, constchar *types) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * Adds a property to a class. * * @param cls The class to modify. * @param name The name of the property. * @param attributes An array of property attributes. * @param attributeCount The number of attributes in \e attributes. * * @return \c YES if the property was added successfully, otherwise \c NO * (for example, the class already has that property). */ OBJC_EXPORT BOOL class_addProperty(Class cls, constchar *name, constobjc_property_attribute_t *attributes, unsignedint attributeCount) OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Adds a new method to a class with a given name and implementation. * * @param cls The class to which to add a method. * @param name A selector that specifies the name of the method being added. * @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd. * @param types An array of characters that describe the types of the arguments to the method. * * @return YES if the method was added successfully, otherwise NO * (for example, the class already contains a method implementation with that name). * * @note class_addMethod will add an override of a superclass's implementation, * but will not replace an existing implementation in this class. * To change an existing implementation, use method_setImplementation. */ OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, constchar *types) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
1 2 3 4 5 6 7 8 9 10 11
/** * Adds a protocol to a class. * * @param cls The class to modify. * @param protocol The protocol to add to \e cls. * * @return \c YES if the method was added successfully, otherwise \c NO * (for example, the class already conforms to that protocol). */ OBJC_EXPORT BOOL class_addProtocol(Class cls, Protocol *protocol) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);