/// An opaque type that represents a method in a class definition.
//一个类的方法
typedef struct objc_method *Method;
/// An opaque type that represents an instance variable.
//实例变量
typedef struct objc_ivar *Ivar;
/// An opaque type that represents a category.
//分类
typedef struct objc_category *Category;
/// An opaque type that represents an Objective-C declared property.
//属性
typedef struct objc_property *objc_property_t;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class //父类 OBJC2_UNAVAILABLE;
const char *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 *` */
#endif
#ifdef __OBJC__
@class Protocol;
#else
typedef struct objc_object Protocol;
#endif
/// Defines a method
//方法描述
struct objc_method_description {
SEL name; /**< The name of the method */
char *types; /**< The types of the method arguments */
};
/// Defines a property attribute
//属性结构体
typedef struct {
const char *name; //属性名 /**< The name of the attribute */
const char *value; //属性值 /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;
/**
* 拷贝一个对象
*
* @param obj
* @param size 对象的大小
*
* @return ID 对象
*/
OBJC_EXPORT id object_copy(id obj, size_t size)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
OBJC_ARC_UNAVAILABLE;
/**
* 释放一个对象
*
* @param obj 对象
*
*/
OBJC_EXPORT id object_dispose(id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
OBJC_ARC_UNAVAILABLE;
/**
* 获取一个类
*
* @param obj 对象名
*
* @return 类
*/
OBJC_EXPORT Class object_getClass(id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 根据一个对象设置一个类
*
* @param obj 对象
* @param cls 类
*
* @return 返回一个类
*/
OBJC_EXPORT Class object_setClass(id obj, Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 判断对象是否是一个类
*
* @param obj 对象
*
* @return 是否是一个对象
*/
OBJC_EXPORT BOOL object_isClass(id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);
/**
* 根据对象获取一个类名
*
* @param obj 对象
*
* @return 类名
*/
OBJC_EXPORT const char *object_getClassName(id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取一个实例变量的值
*
* @param obj 对象
* @param ivar 实例变量
*
*/
OBJC_EXPORT id object_getIvar(id obj, Ivar ivar)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 给一个对象的实例变量设置值
*
* @param obj 对象
* @param ivar 实例变量
* @param value 值
*/
OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 修改对象实例变量
*
* @param obj 对象
* @param name 属性名
* @param value 值
*/
OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *value)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
OBJC_ARC_UNAVAILABLE;
/**
* 获取对象实例变量
*
* @param obj 对象
* @param name 属性名
* @param value 值
*/
OBJC_EXPORT Ivar object_getInstanceVariable(id obj, const char *name, void **outValue);
/*** 类相关函数 ***/
/**
* 根据一个类名 获取一个类
*
* @param name 名字
*
* @return 类
*/
OBJC_EXPORT Class objc_getClass(const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取一个元类
*
* @param name 类名
*
* @return 元类
*/
OBJC_EXPORT Class objc_getMetaClass(const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取注册类的缓存数量
*
* @param buffer 注册的数组
* @param bufferCount 数量
*
*/
OBJC_EXPORT int objc_getClassList(Class *buffer, int bufferCount)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 拷贝已注册的类
*
* @param outCount 数量
*
*/
OBJC_EXPORT Class *objc_copyClassList(unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_3_1);
/* 类相关函数 */
/**
* 获取类名
*
* @param cls 类
*
* @return 类名
*/
OBJC_EXPORT const char *class_getName(Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 判断类是否是元类
*
* @param cls 类
*
* @return 是否是元类
*/
OBJC_EXPORT BOOL class_isMetaClass(Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取当前类的父类
*
* @param cls 当期类
*
* @return 父类
*/
OBJC_EXPORT Class class_getSuperclass(Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 给当前类设置父类
*
* @param cls 当前类
* @param newSuper 父类
*
* @return 当前类
*/
OBJC_EXPORT Class class_setSuperclass(Class cls, Class newSuper)
__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_5, __IPHONE_2_0,__IPHONE_2_0);
/**
* 获取类的大小
*
* @param cls 当前类
*
* @return 大小
*/
OBJC_EXPORT size_t class_getInstanceSize(Class cls);
/**
* 获取当前实例的成员变量的值
*
* @param cls 当前类
* @param name 成员变量名
*
* @return 成员变量
*/
OBJC_EXPORT Ivar class_getInstanceVariable(Class cls, const char *name);
/**
* 获取当前类的成员变量的值
*
* @param cls 当前类
* @param name 成员变量名
*
* @return 成员变量
*/
OBJC_EXPORT Ivar class_getClassVariable(Class cls, const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝一个类的属性链表--数组
*
* @param cls 当前类
* @param 数量
*
* @return 该类的所有属性
*/
OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取实例的方法
*
* @param cls 类
* @param name 方法名
*
* @return Method 方法
*/
OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取类方法
*
* @param cls 类
* @param name 方法名
*
* @return 类方法
*/
OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取类方法实现
*
* @param cls 当前类
* @param name 方法名
*
* @return 方法的实现
*/
OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取类方法实现
*
* @param cls 当前类
* @param name 方法名
*
* @return 方法的实现
*/
OBJC_EXPORT IMP class_getMethodImplementation_stret(Class cls, SEL name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
OBJC_ARM64_UNAVAILABLE;
/**
* 判断Selector是否响应
*
* @param cls 类
* @param sel Selector
*
* @return 是否响应
*/
OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取一个类的方法列表
*
* @param cls 类
* @param outCount 数量
*
* @return 所有方法
*/
OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 检查是否符合协议
*
* @param cls 类
* @param protocol 协议
*
* @return 是否符合与父类无关
*/
OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝所有协议列表
*
* @param cls 类
* @param outCount 数量
*
* @return 协议列表
*/
OBJC_EXPORT Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取一个对象的属性
*
* @param cls 类
* @param name 属性名
*
* @return 属性
*/
OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝属性列表
*
* @param cls 类
* @param outCount 属性数量
*
* @return 属性列表
*/
OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 动态的给类添加一个方法和实现
*
* @param cls 类
* @param name 方法名
* @param imp 方法实现
* @param types 方法类型
*
* @return 是否添加成功
*/
OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp,
const char *types)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 动态的移除一个类的方法和实现
*
* @param cls 类
* @param name 方法名
* @param imp 实现
* @param types 方法类型
*
* @return 是否移除成功
*/
OBJC_EXPORT IMP class_replaceMethod(Class cls, SEL name, IMP imp,
const char *types)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 添加一个新的实例变量
*
* @return 是否添加成功
*
* @note 添加的这个成员变量是不存在的
* @note 这个类不能是元类,元类是不支持添加的
*/
OBJC_EXPORT BOOL class_addIvar(Class cls, const char *name, size_t size,
uint8_t alignment, const char *types)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 给类添加一个协议
*
* @param cls 当前类.
* @param protocol 协议.
*
* @return 是否添加成功
*/
OBJC_EXPORT BOOL class_addProtocol(Class cls, Protocol *protocol)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 给类添加一个属性
*
* @param cls 这个类已经修改了.
* @param name 属性名.
* @param attributes property数组.
* @param attributeCount property数组长度.
*
* @return 是否添加成功
*/
OBJC_EXPORT BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 移除一个属性
*
* @param cls 这个类已经修改了
* @param name 属性名
* @param attributes property 数组.
* @param attributeCount property 数组长度
*/
OBJC_EXPORT void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/* 实例化一个类 相关 */
/**
* 实例化一个类
*
* @param cls 类
* @param extraBytes 大小
*
* @return 实例化的类
*/
OBJC_EXPORT id class_createInstance(Class cls, size_t extraBytes)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
OBJC_ARC_UNAVAILABLE;
/* 添加一个类 */
/**
* 创建一个新的类或者是元类
*
* @param superclass 父类
* @param name The 类名
* @param extraBytes 类大小
*
* @return 创建好的类
*
*/
OBJC_EXPORT Class objc_allocateClassPair(Class superclass, const char *name,
size_t extraBytes)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 注册一个类
*
*/
OBJC_EXPORT void objc_registerClassPair(Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/* 方法相关 */
/**
* 获取一个方法
*
* @param m 方法
*
* @return 方法
*/
OBJC_EXPORT SEL method_getName(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取一个方法实现
*
* @param m 方法
*
* @return 方法的实现
*/
OBJC_EXPORT IMP method_getImplementation(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取方法的类型编码
*
* @param m 方法
*
* @return 类型编码
*/
OBJC_EXPORT const char *method_getTypeEncoding(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取方法的参数数量
*
* @param m 方法
*
* @return 参数数量
*/
OBJC_EXPORT unsigned int method_getNumberOfArguments(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 拷贝方法的返回类型
*
* @param m 方法
*
* @return 返回类型
*/
OBJC_EXPORT char *method_copyReturnType(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 根据索引拷贝参数类型
*
* @param m 方法
* @param index 索引
*
* @return 参数类型
*/
OBJC_EXPORT char *method_copyArgumentType(Method m, unsigned int index)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取方法的返回类型
*
* @param m 方法
* @param dst 引用的字符串存储描述。
* @param dst_len 大小
*
*/
OBJC_EXPORT void method_getReturnType(Method m, char *dst, size_t dst_len)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 根据索引获取参数类型
*
* @param m 方法
* @param index 索引
* @param dst_len 长度
*/
OBJC_EXPORT void method_getArgumentType(Method m, unsigned int index,
char *dst, size_t dst_len)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
OBJC_EXPORT struct objc_method_description *method_getDescription(Method m)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 设置方法的实现
*
* @param m 方法
* @param imp 实现
*
*/
OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 交换两个方法
*
* @param m1 方法1
* @param m2 方法2
*/
OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/* 实例变量相关 */
/**
* 获取实例变量名
*
* @param v 实力编码
*
* @return 实例变量名
*/
OBJC_EXPORT const char *ivar_getName(Ivar v)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取实例变量编码
*
* @param v 实例变量
*
* @return A 类型编码
*
*/
OBJC_EXPORT const char *ivar_getTypeEncoding(Ivar v)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取实例变量便宜地址
*
* @param v 实例变量
*
* @return 偏移地址
*/
OBJC_EXPORT ptrdiff_t ivar_getOffset(Ivar v)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/* 属性相关 */
/**
* 获取属性名
*
* @param property 属性
*
* @return 属性名
*/
OBJC_EXPORT const char *property_getName(objc_property_t property)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取 property 的 attributes
*
* @param property A property.
*
*/
OBJC_EXPORT const char *property_getAttributes(objc_property_t property)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝 property 的 attributes 列表
*
* @param outCount 数量
*
*/
OBJC_EXPORT objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 拷贝 property 的 attribute 列表的值
*
* @param property The property whose attribute value you are interested in.
* @param attributeName attributeName名.
*
* @return The value string of the attribute \e attributeName if it exists in
* \e property, \c nil otherwise.
*/
OBJC_EXPORT char *property_copyAttributeValue(objc_property_t property, const char *attributeName)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/* 协议相关 */
/**
* 根据名字获取协议
*
* @param name 协议名.
*
*/
OBJC_EXPORT Protocol *objc_getProtocol(const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝协议列表
*
* @param outCount 遵守协议的数量
*
* @return A C array 协议列表
*/
OBJC_EXPORT Protocol * __unsafe_unretained *objc_copyProtocolList(unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 检查A协议是否符合另一个协议
*
* @param proto A protocol.
* @param other A protocol.
*
*/
OBJC_EXPORT BOOL protocol_conformsToProtocol(Protocol *proto, Protocol *other)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 判断两个协议是否相等
*
* @param proto A protocol.
* @param other A protocol.
*
* @return 是否相等
*/
OBJC_EXPORT BOOL protocol_isEqual(Protocol *proto, Protocol *other)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取协议名
*
* @param p A protocol.
*
* @return The name of the protocol \e p as a C string.
*/
OBJC_EXPORT const char *protocol_getName(Protocol *p)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 返回一个指定的方法的方法描述结构给定的协议。
*
* @param p A protocol.
* @param aSel A selector.
* @param isRequiredMethod A Boolean value that indicates whether aSel is a required method.
* @param isInstanceMethod A Boolean value that indicates whether aSel is an instance method.
*
* @return An \c objc_method_description structure that describes the method specified by \e aSel,
* \e isRequiredMethod, and \e isInstanceMethod for the protocol \e p.
* If the protocol does not contain the specified method, returns an \c objc_method_description structure
* with the value \c {NULL, \c NULL}.
*
* @note This function recursively searches any protocols that this protocol conforms to.
*/
OBJC_EXPORT struct objc_method_description protocol_getMethodDescription(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* Returns an array of method descriptions of methods meeting a given specification for a given protocol.
*
* @param p A protocol.
* @param isRequiredMethod A Boolean value that indicates whether returned methods should
* be required methods (pass YES to specify required methods).
* @param isInstanceMethod A Boolean value that indicates whether returned methods should
* be instance methods (pass YES to specify instance methods).
* @param outCount Upon return, contains the number of method description structures in the returned array.
*
* @return A C array of \c objc_method_description structures containing the names and types of \e p's methods
* specified by \e isRequiredMethod and \e isInstanceMethod. The array contains \c *outCount pointers followed
* by a \c NULL terminator. You must free the list with \c free().
* If the protocol declares no methods that meet the specification, \c NULL is returned and \c *outCount is 0.
*
* @note Methods in other protocols adopted by this protocol are not included.
*/
OBJC_EXPORT struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 获取协议属性
*
* @param proto A protocol.
* @param name The name of a property.
* @param isRequiredProperty A Boolean value that indicates whether name is a required property.
* @param isInstanceProperty A Boolean value that indicates whether name is a required property.
*
* @return The property specified by \e name, \e isRequiredProperty, and \e isInstanceProperty for \e proto,
* or \c NULL if none of \e proto's properties meets the specification.
*/
OBJC_EXPORT objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝协议的属性列表
*
* @param proto A protocol.
* @param outCount Upon return, contains the number of elements in the returned array.
*
* @return A C array of pointers of type \c objc_property_t describing the properties declared by \e proto.
* Any properties declared by other protocols adopted by this protocol are not included. The array contains
* \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().
* If the protocol declares no properties, \c NULL is returned and \c *outCount is \c 0.
*/
OBJC_EXPORT objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 拷贝协议列表(线程不安全)
*
* @param proto A protocol.
* @param outCount Upon return, contains the number of elements in the returned array.
*
* @return A C array of protocols adopted by \e proto. The array contains \e *outCount pointers
* followed by a \c NULL terminator. You must free the array with \c free().
* If the protocol declares no properties, \c NULL is returned and \c *outCount is \c 0.
*/
OBJC_EXPORT Protocol * __unsafe_unretained *protocol_copyProtocolList(Protocol *proto, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 创建一个新的协议
*
*
* @param name 协议名字.
*
*/
OBJC_EXPORT Protocol *objc_allocateProtocol(const char *name)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 注册协议
*
*/
OBJC_EXPORT void objc_registerProtocol(Protocol *proto)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 给协议添加一个方法
*
* @param proto The protocol to add a method to.
* @param name The name of the method to add.
* @param types A C string that represents the method signature.
* @param isRequiredMethod YES if the method is not an optional method.
* @param isInstanceMethod YES if the method is an instance method.
*/
OBJC_EXPORT void protocol_addMethodDescription(Protocol *proto, SEL name, const char *types, BOOL isRequiredMethod, BOOL isInstanceMethod)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 添加一个协议
*
* @param proto The protocol you want to add to, it must be under construction.
* @param addition The protocol you want to incorporate into \e proto, it must be registered.
*/
OBJC_EXPORT void protocol_addProtocol(Protocol *proto, Protocol *addition)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* 给协议添加一个属性
*
* @param proto The protocol to add a property to.
* @param name The name of the property.
* @param attributes An array of property attributes.
* @param attributeCount The number of attributes in \e attributes.
* @param isRequiredProperty YES if the property (accessor methods) is not optional.
* @param isInstanceProperty YES if the property (accessor methods) are instance methods.
* This is the only case allowed fo a property, as a result, setting this to NO will
* not add the property to the protocol at all.
*/
OBJC_EXPORT void protocol_addProperty(Protocol *proto, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount, BOOL isRequiredProperty, BOOL isInstanceProperty)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/* 镜像相关 */
/**
* 拷贝镜像名
*
* @param outCount The number of names returned.
*
* @return An array of C strings of names. Must be free()'d by caller.
*/
OBJC_EXPORT const char **objc_copyImageNames(unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 根据一个类获取镜像名
*
* @param cls 当前类
*
* @return 包含这个类库的名称
*/
OBJC_EXPORT const char *class_getImageName(Class cls)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 返回一个库中所有的类的名称列表。
*
* @param image 你询问的库或框架.
* @param outCount 数量.
*
*/
OBJC_EXPORT const char **objc_copyClassNamesForImage(const char *image,
unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/* Selectors 相关 */
/**
* 获取SEL的名称
*
* @param sel 选择器.
*
*/
OBJC_EXPORT const char *sel_getName(SEL sel)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 获取一个Selectors的Uid
*
* @param str Selectors 名
*
*/
OBJC_EXPORT SEL sel_getUid(const char *str)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 注册Selectors
*
*
* @param str Selectors名
*
* @return A pointer of type SEL specifying the selector for the named method.
*
*/
OBJC_EXPORT SEL sel_registerName(const char *str)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/**
* 判断Selectors是否相等
*
* @param lhs A Selectors .
* @param rhs B Selectors
*
* @return 是否相等
*
*/
OBJC_EXPORT BOOL sel_isEqual(SEL lhs, SEL rhs)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/* Objective-C Language 特征 */
/**
* This function is inserted by the compiler when a mutation
* is detected during a foreach iteration. It gets called
* when a mutation occurs, and the enumerationMutationHandler
* is enacted if it is set up. A fatal error occurs if a handler is not set up.
*
* @param obj The object being mutated.
*
*/
OBJC_EXPORT void objc_enumerationMutation(id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* Sets the current mutation handler.
*
* @param handler Function pointer to the new mutation handler.
*/
OBJC_EXPORT void objc_setEnumerationMutationHandler(void (*handler)(id))
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* Set the function to be called by objc_msgForward.
*
* @param fwd Function to be jumped to by objc_msgForward.
* @param fwd_stret Function to be jumped to by objc_msgForward_stret.
*
* @see message.h::_objc_msgForward
*/
OBJC_EXPORT void objc_setForwardHandler(void *fwd, void *fwd_stret)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* Creates a pointer to a function that will call the block
* when the method is called.
*
* @param block The block that implements this method. Its signature should
* be: method_return_type ^(id self, method_args...).
* The selector is not available as a parameter to this block.
* The block is copied with \c Block_copy().
*
* @return The IMP that calls this block. Must be disposed of with
* \c imp_removeBlock.
*/
OBJC_EXPORT IMP imp_implementationWithBlock(id block)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* Return the block associated with an IMP that was created using
* \c imp_implementationWithBlock.
*
* @param anImp The IMP that calls this block.
*
* @return The block called by \e anImp.
*/
OBJC_EXPORT id imp_getBlock(IMP anImp)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* Disassociates a block from an IMP that was created using
* \c imp_implementationWithBlock and releases the copy of the
* block that was created.
*
* @param anImp An IMP that was created using \c imp_implementationWithBlock.
*
* @return YES if the block was released successfully, NO otherwise.
* (For example, the block might not have been used to create an IMP previously).
*/
OBJC_EXPORT BOOL imp_removeBlock(IMP anImp)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
/**
* This loads the object referenced by a weak pointer and returns it, after
* retaining and autoreleasing the object to ensure that it stays alive
* long enough for the caller to use it. This function would be used
* anywhere a __weak variable is used in an expression.
*
* @param location The weak pointer address
*
* @return The object pointed to by \e location, or \c nil if \e location is \c nil.
*/
OBJC_EXPORT id objc_loadWeak(id *location)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
/**
* This function stores a new value into a __weak variable. It would
* be used anywhere a __weak variable is the target of an assignment.
*
* @param location The address of the weak pointer itself
* @param obj The new object this weak ptr should now point to
*
* @return The value stored into \e location, i.e. \e obj
*/
OBJC_EXPORT id objc_storeWeak(id *location, id obj)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
/* Associative References */
/**
* Policies related to associative references.
* These are options to objc_setAssociatedObject()
*/
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
* The association is made atomically. */
OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
* The association is made atomically. */
};
/**
* 设置关联对象
*
* @param object 源对象
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
/**
* 根据Key获取关联的对象
*
* @param object The source object for the association.
* @param key The key for the association.
*
* @return The value associated with the key \e key for \e object.
*
* @see objc_setAssociatedObject
*/
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
/**
* 移除当前对象的所有关联
*
* @param object An object that maintains associated objects.
*
* @note The main purpose of this function is to make it easy to return an object
* to a "pristine state”. You should not use this function for general removal of
* associations from objects, since it also removes associations that other clients
* may have added to the object. Typically you should use \c objc_setAssociatedObject
* with a nil value to clear an association.
*
* @see objc_setAssociatedObject
* @see objc_getAssociatedObject
*/
OBJC_EXPORT void objc_removeAssociatedObjects(id object)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
#define _C_ID '@'
#define _C_CLASS '#'
#define _C_SEL ':'
#define _C_CHR 'c'
#define _C_UCHR 'C'
#define _C_SHT 's'
#define _C_USHT 'S'
#define _C_INT 'i'
#define _C_UINT 'I'
#define _C_LNG 'l'
#define _C_ULNG 'L'
#define _C_LNG_LNG 'q'
#define _C_ULNG_LNG 'Q'
#define _C_FLT 'f'
#define _C_DBL 'd'
#define _C_BFLD 'b'
#define _C_BOOL 'B'
#define _C_VOID 'v'
#define _C_UNDEF '?'
#define _C_PTR '^'
#define _C_CHARPTR '*'
#define _C_ATOM '%'
#define _C_ARY_B '['
#define _C_ARY_E ']'
#define _C_UNION_B '('
#define _C_UNION_E ')'
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
#define _C_VECTOR '!'
#define _C_CONST 'r'
/* Obsolete types */
#if !__OBJC2__
#define CLS_GETINFO(cls,infomask) ((cls)->info & (infomask))
#define CLS_SETINFO(cls,infomask) ((cls)->info |= (infomask))
// class is not a metaclass
#define CLS_CLASS 0x1
// class is a metaclass
#define CLS_META 0x2
// class's +initialize method has completed
#define CLS_INITIALIZED 0x4
// class is posing
#define CLS_POSING 0x8
// unused
#define CLS_MAPPED 0x10
// class and subclasses need cache flush during image loading
#define CLS_FLUSH_CACHE 0x20
// method cache should grow when full
#define CLS_GROW_CACHE 0x40
// unused
#define CLS_NEED_BIND 0x80
// methodLists is array of method lists
#define CLS_METHOD_ARRAY 0x100
// the JavaBridge constructs classes with these markers
#define CLS_JAVA_HYBRID 0x200
#define CLS_JAVA_CLASS 0x400
// thread-safe +initialize
#define CLS_INITIALIZING 0x800
// bundle unloading
#define CLS_FROM_BUNDLE 0x1000
// C++ ivar support
#define CLS_HAS_CXX_STRUCTORS 0x2000
// Lazy method list arrays
#define CLS_NO_METHOD_ARRAY 0x4000
// +load implementation
#define CLS_HAS_LOAD_METHOD 0x8000
// objc_allocateClassPair API
#define CLS_CONSTRUCTING 0x10000
// class compiled with bigger class structure
#define CLS_EXT 0x20000
struct objc_method_description_list {
int count;
struct objc_method_description list[1];
};
struct objc_protocol_list { //协议列表
struct objc_protocol_list *next;//下一个协议
long count;//数量
Protocol *list[1];
};
struct objc_category {
char *category_name //分类名
char *class_name //类名
struct objc_method_list *instance_methods //实例方法列表 ;
struct objc_method_list *class_methods //类方法列表 ;
struct objc_protocol_list *protocols //协议列表 ;
} ;
struct objc_ivar {
char *ivar_name //成员变量名 OBJC2_UNAVAILABLE;
char *ivar_type //成员变量类型 OBJC2_UNAVAILABLE;
int ivar_offset //成员变量偏移地址 OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
struct objc_ivar_list { //成员变量列表
int ivar_count //成员变量数量 OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
struct objc_method { //对象方法
SEL method_name //方法名 OBJC2_UNAVAILABLE;
char *method_types //方法类型 OBJC2_UNAVAILABLE;
IMP method_imp //方法实现 OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
struct objc_method_list { //方法列表
struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
int method_count //方法数量 OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
typedef struct objc_symtab *Symtab OBJC2_UNAVAILABLE;
struct objc_symtab {
unsigned long sel_ref_cnt OBJC2_UNAVAILABLE;
SEL *refs OBJC2_UNAVAILABLE;
unsigned short cls_def_cnt OBJC2_UNAVAILABLE;
unsigned short cat_def_cnt OBJC2_UNAVAILABLE;
void *defs[1] /* variable size */ OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
typedef struct objc_cache *Cache //方法缓存 OBJC2_UNAVAILABLE;
#define CACHE_BUCKET_NAME(B) ((B)->method_name)
#define CACHE_BUCKET_IMP(B) ((B)->method_imp)
#define CACHE_BUCKET_VALID(B) (B)
#ifndef __LP64__
#define CACHE_HASH(sel, mask) (((uintptr_t)(sel)>>2) & (mask))
#else
#define CACHE_HASH(sel, mask) (((unsigned int)((uintptr_t)(sel)>>3)) & (mask))
#endif
struct objc_cache { // 方法缓存
unsigned int mask /* total = mask + 1 */ OBJC2_UNAVAILABLE;
unsigned int occupied OBJC2_UNAVAILABLE;
Method buckets[1] OBJC2_UNAVAILABLE;
};
typedef struct objc_module *Module OBJC2_UNAVAILABLE;
struct objc_module {
unsigned long version OBJC2_UNAVAILABLE;
unsigned long size OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
Symtab symtab OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
#else
struct objc_method_list;
#endif
#endif