runtime 就是运行时机制 ,可以动态的增加一个类 给类添加属性 方法或者是新建一个类
或者是改变类的实现方法
oc 其实就是一种运行时语言 和 c++ 不同是的c++在编译的时候 就已经 直接把函数地址写进可执行文件 。而oc是在程序运行的时候 runtime根据条件作出判断 --函数标志和
函数过程的真正内容之间可以动态的修改
下面是对runtime源码的一些解读
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class 指向父类的指针
const char *name 类名
long version 类版本号
long info
long instance_size 对象的占用空间
struct objc_ivar_list *ivars 所有的属性
struct objc_method_list **methodLists 所有的 方法
struct objc_cache *cache 调用的方法 会储存在这个里面 如果方便下次直接调用 。方便下次直接调用 不用再找一遍 是通过
标志符号 SEL 查找的
struct objc_protocol_list *protocols 遵守的协议
#endif
} OBJC2_UNAVAILABLE;
这就是oc中类的定义 class 就是指向 objc_class 的结构体的一个指针 objc_class结构体 包含了类的一些基本的信息
struct objc_ivar_list *ivars
struct objc_ivar_list {
int ivar_count 属性的数量
#ifdef __LP64__
int space 占用空间的大小
#endif
/* variable length structure */
struct objc_ivar ivar_list[1] 结构体 objc_ivar(其实就是属性)的数组
}
ivars 其实就是指向了这样的一个结构体 的指针
struct objc_ivar ivar_list[1]
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
}
结构体 就是这个 类的属性
struct objc_method_list {
struct objc_method_list *obsolete
int method_count 方法数量
#ifdef __LP64__
int space 占用的空间
#endif
/* variable length structure */
struct objc_method method_list[1] objc_method 数组
}
这个结构体存储 了类的方法列表
下面是一个方法的定义
struct objc_method {
SEL method_name sel类型标识符 OBJC2_UNAVAILABLE;
char *method_types 方法类型 参数 和 返回值类型
IMP method_imp 具体的函数指针 OBJC2_UNAVAILABLE;
}
SEL 是指向这个结构体的指针
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...); 一个函数指针
这就是oc中一个方法 的定义 因为 类中的方法
runtime方法介绍
object_getClass(id obj)
/**
* 返回对象的类的isa 指针
*
* @param obj 你想检查的对象
*
* @return 返回这个对象的isa指针 ,
* or Nil if object is nil.
*/
OBJC_EXPORT Class object_getClass(id obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
这个方法是返回 对象的isa指针 的方法 对 调用的是对象的时候 和【objc class】返回的class 是一样的都是isa 指针 当 调用的是类对象的时候 object_getClass(id obj) 返回的是类对象的isa 指针 。指向的是元类对象 。 类对象调用【objc class】返回的是自己本身
object_setClass(id obj,Class cls)
/**
* 给对象设置一个类
*
* @param obj The object to modify.
* @param cls A class object.
*
* @return The previous value of \e object's class, or \c Nil if \e object is \c nil.
*/
OBJC_EXPORT Class object_setClass(id obj, Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
给一个对象 设置成别的类
person *people = [[person alloc]init];
people.name = @"张文勇";
[people class];
//设置类
object_setClass(people, [dog class]);
获取对象所属的类
NSLog(@"==%@==",object_getClass(people));
object_isClass(id obj)
/**
* 判断一个对象是否是类对象
*
* Returns whether an object is a class object.
*
* @param obj An Objective-C object.
*
* @return true if the object is a class or metaclass, false otherwise.
*/
OBJC_EXPORT BOOL object_isClass(id obj)
OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0);
object_getIvar(id obj,Ivar ivar)
/**
* 读取实例对象属性的值
* Reads the value of an instance variable in an object.
*
* @param obj 对象.
* @param ivar The Ivar describing the instance variable whose value you want to read.
*
* @return 返回属性的值 如果obj是空则返回nil
*
* @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar
* for the instance variable is already known.
*/
OBJC_EXPORT id object_getIvar(id obj, Ivar ivar)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
这个方法 是获取对象 属性的值的方法。 举例子如下
先出初始化一个对象
person *people = [[person alloc]init];
people.name = @"张文勇";
通过 objec_getClass()获取这个对象的isa指针 看看属于哪个类
然后再 获取 这个类的一个name的Ivar 属性
Ivar ivar = class_getInstanceVariable(object_getClass(people), "_name");
// 然后通过这个属性 object_getIvar(id obj,Ivar ivar);获取属性值
NSString *name = object_getIvar(people, ivar);
NSLog(@"%@",name);
object_setIvar(id obj,Ivar ivar,id value)
给对象的某一个属性赋值
/**
* 给对象的属性赋值
*
* @param obj 要赋值的对象.
* @param ivar 描述变量属性的Ivar
The Ivar describing the instance variable whose value you want to set.
* @param value 要赋的值
*
* @note 变量属性 with known memory management (such as ARC strong and weak)
* use that memory management. I
如果对象没有 默认 的 memory management 就使用unsafe_unretained;
nstance variables with unknown memory management 。
* are assigned as if they were unsafe_unretained.
* @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar
* for the instance variable is already known.
*/
OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
如果对象没有 默认 的 memory management 就使用unsafe_unretained;
这个方方法 再ARC可用
例子
person *people = [[person alloc]init];
people.name = @"张文勇";
Ivar ivar = class_getInstanceVariable(object_getClass(people), "_name");
NSString *name = object_getIvar(people, ivar);
//给对想得到某个属性赋值 给对象的某个属性赋值
给对象的某个属性赋值 。给对象的某个属性赋值
object_setIvar(people, ivar, @"tianya");
NSLog(@"%@",people.name);
bject_setIvarWithStrongDefault(id obj, Ivar ivar, id value)
这个方法 和上个方法 基本一致唯一的区别 就是属性如果没有默认memory management 就实用strong 类型的 。
/**
* Sets the value of an instance variable in an object.
*
* @param obj The object containing the instance variable whose value you want to set.
* @param ivar The Ivar describing the instance variable whose value you want to set.
* @param value The new value for the instance variable.
*
* @note Instance variables with known memory management (such as ARC strong and weak)
* use that memory management. Instance variables with unknown memory management
* are assigned as if they were strong.
* @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar
* for the instance variable is already known.
*/
OBJC_EXPORT void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0);
Obtaining Class Definitions获取类定义
*objc_getClass(const char name)
根据类的字符串的名字获取类
/**
* Returns the class definition of a specified class.
*
* @param name The name of the class to look up.
*
* @return The Class object for the named class, or \c nil
* if the class is not registered with the Objective-C runtime.
*
* @note \c objc_getClass is different from \c objc_lookUpClass in that if the class
* is not registered, \c objc_getClass calls the class handler callback and then checks
* a second time to see whether the class is registered. \c objc_lookUpClass does
* not call the class handler callback.
*
* @warning Earlier implementations of this function (prior to OS X v10.0)
* terminate the program if the class does not exist.
*/
OBJC_EXPORT Class objc_getClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
objc_getClass(const char *name) 获取类的例子
根据类的名字获取类对象 。
Class ddd = objc_getClass("person");
根据类对象 获取_name属性
Ivar ivar= class_getInstanceVariable(ddd, "_name");
类实例化对象
id ccc = [[ddd alloc]init];
给对象 _name 属性添加 属性址
object_setIvar(ccc, ivar, @"dwedwe");
获取实例对象的属性值
NSLog(@"%@",object_getIvar(ccc, ivar));
*objc_getMetaClass(const char name)
根据字符串得到 类对象的元类
/**
* Returns the metaclass definition of a specified class.
*
* @param name The name of the class to look up.
*
* @return The \c Class object for the metaclass of the named class, or \c nil if the class
* is not registered with the Objective-C runtime.
*
* @note If the definition for the named class is not registered, this function calls the class handler
* callback and then checks a second time to see if the class is registered. However, every class
* definition must have a valid metaclass definition, and so the metaclass definition is always returned,
* whether it’s valid or not.
*/
OBJC_EXPORT Class objc_getMetaClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
objc_getRequiredClass
这个方法 和 objc_getClass(const char *name)方法一下样都是根据类的字符串的名字返回一个
类对象 。不过这个方法 如果找不到类会直接 crash 程序
/**
* Returns the class definition of a specified class.
*
* @param name 需要找的类的名字 。需要找的类的名字 需要找的类的名字
*
* @return 类对象.
*
* @note This function is the same as \c objc_getClass, but kills the process if the class is not found.
* @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink.
*/
OBJC_EXPORT Class objc_getRequiredClass(const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
*int objc_getClasssList(class buffer,int buffercount)
这个方法是获取注册类的总数 class *buffer是储存所有的类数组
/**
* Obtains the list of registered class definitions.
*
* @param buffer An array of \c Class values. On output, each \c Class value points to
* one class definition, up to either \e bufferCount or the total number of registered classes,
* whichever is less. You can pass \c NULL to obtain the total number of registered class
* definitions without actually retrieving any class definitions.
* @param bufferCount An integer value. Pass the number of pointers for which you have allocated space
* in \e buffer. On return, this function fills in only this number of elements. If this number is less
* than the number of registered classes, this function returns an arbitrary subset of the registered classes.
*
* @return An integer value indicating the total number of registered classes.
*
* @note The Objective-C runtime library automatically registers all the classes defined in your source code.
* You can create class definitions at runtime and register them with the \c objc_addClass function.
*
* @warning You cannot assume that class objects you get from this function are classes that inherit from \c NSObject,
* so you cannot safely call any methods on such classes without detecting that the method is implemented first.
*/
OBJC_EXPORT int objc_getClassList(Class *buffer, int bufferCount)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
利用这个方法 可以获取所有已经注册的类 代码实战
int classcount = 0;
首先获取所有的类的中数
classcount = objc_getClassList(NULL, 0);
Class *buffbuffer1 = NULL;
根据类的总数给数组分配空间
buffbuffer1 = (Class *)malloc(sizeof(Class)*classcount);
然后获取类的总数 并且 把所有的类存储在数组中
objc_getClassList(buffbuffer1, classcount);
for(int i=0;i<classcount;i++)
{
根据类对象获取类的名字 打印类名字
const char *dd = class_getName(buffbuffer1[i]);
printf("%s\n",dd);
}
free(buffbuffer1);
buffbuffer1 = NULL;
objc_copyClassList(unsigned int outcount)
这个方法 和上面的getClassList的方法一样 不过更简单 也是获取所有的已经住的类
/**
* Creates and returns a list of pointers to all registered class definitions.
*
* @param outCount An integer pointer used to store the number of classes returned by
* this function in the list. It can be \c nil.
*
* @return A nil terminated array of classes. It must be freed with \c free().
*
* @see objc_getClassList
*/
OBJC_EXPORT Class *objc_copyClassList(unsigned int *outCount)
OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0);
代码实例
Class *buffbuffer1 = objc_copyClassList(&classcount);
free(buffbuffer1);
Working with Classes类方法
class_getName(Class cls)
根据类 对象获取了类的字符串名字
/**
* 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 const char *class_getName(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
代码实例
Class dd = [person class];
class_getName(dd);
class_isMetaClass
判断一个类是否是元类
/**
* Returns a Boolean value that indicates whether a class object is a metaclass.
*
* @param cls A class object.
*
* @return \c YES if \e cls is a metaclass, \c NO if \e cls is a non-meta class,
* \c NO if \e cls is \c Nil.
*/
OBJC_EXPORT BOOL class_isMetaClass(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_getSuperclass
返回这个类的父类
/**
* 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);
代码实例
Class dd = [person class];
获取赋类
Class ddc = class_getSuperclass(dd);
获取 类的名字
const char *ddda = class_getName(ddc);
printf("%s\n",ddda);
class_getVersion
获取类的版本号
/**
* 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);
class_setVersion
OBJC_EXPORT void class_setVersion(Class cls, int version)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
class_getInstanceSize
获取实例变量的大小
/**
* 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);
*class_getInstaceVarialble(class cls,const char name)
根据属性的名字获取类的某一个属性
/**
* Returns the \c Ivar for a specified instance variable of a given class.
*
* @param cls The class whose instance variable you wish to obtain.
* @param name The name of the instance variable definition to obtain.
*
* @return A pointer to an \c Ivar data structure containing information about
* the instance variable specified by \e name.
*/
OBJC_EXPORT Ivar class_getInstanceVariable(Class cls, const char *name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
classes_copyIvarList(Class cls,unsigned int outCount)
获取所有类的所有的属性 获取类的所有的属性 获取类的所有的属性 但是 不会获取父类的属性 只会获取 自己的属性
/**
* Describes the instance variables declared by a class.
*
* @param cls 要检查.
* @param outCount 用于返回 属性数组的长度
* 如果outcount是NULL值则不会返回长度
*
* @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, unsigned int *outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
代码实例
xiaoming *zhang = [[xiaoming alloc]init];
zhang.age = @"dwedw";
Class xiam = [zhang class];
unsigned int count = 0;
//定义一个属性数组的指针
Ivar *list = NULL;
//获取属性数组 。和数组的长度
list = class_copyIvarList(xiam, &count);
for (int i=0;i<count;i++)
{
id huilai;
Ivar ivar = list[i];
获取对象 这个属性的值 。
并且不回获取赋类的这个属性
huilai = object_getIvar(zhang, ivar);
NSLog(@"%@\n",huilai);
}
free(list);
看看这个查找的源码
Ivar *class_copyIvarList(Class cls_gen, unsigned int *outCount)
{
//根据类对象 生成一个 old_class
struct old_class *cls = oldcls(cls_gen);
Ivar *result = NULL;
unsigned int count = 0;
int i;
if (!cls) {
//如果类对象不存在 直接返回
if (outCount) *outCount = 0;
return NULL;
}
if (cls->ivars) {
查看结构体中的 属性里俩啊吗的数量
count = cls->ivars->ivar_count;
}
if (count > 0) {
根据属性数组的数量申请内存
result = malloc((count+1) * sizeof(Ivar));
使用数组去接受 这些 属性
for (i = 0; i < cls->ivars->ivar_count; i++) {
result[i] = (Ivar)&cls->ivars->ivar_list[i];
}
result[i] = NULL;
}
返回
if (outCount) *outCount = count;
return result;
}
class_getInstanceMethod(Class cls,SEL name)
根据SEL获取这个类的对象的实例方法( 包含父类 )
/**
* Returns 返回给定类的实例方法
*
* @param cls 类对象.
* @param name The selector of the method you want to retrieve.
*
* @return The method that corresponds to the implementation of the selector specified by
* \e name for the class specified by \e cls, or \c NULL if the specified class or its
* superclasses do not contain an instance method with the specified selector.
*
* @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not. 这个方法 搜索 父类
*/
OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
class_getClassMethod
获取类方法 ( 包含父类 )
/**
* Returns a pointer to the data structure describing a given class method for a given class.
*
* @param cls A pointer to a class definition. Pass the class that contains the method you want to retrieve.
* @param name A pointer of type \c SEL. Pass the selector of the method you want to retrieve.
*
* @return A pointer to the \c Method data structure that corresponds to the implementation of the
* selector specified by aSelector for the class specified by aClass, or NULL if the specified
* class or its superclasses do not contain an instance method with the specified selector.
*
* @note Note that this function searches superclasses for implementations,
* whereas \c class_copyMethodList does not.
*/
OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
class_getMethodImplementation(Class cls,SEL name)
根据SEL获取对应的执行此消息是 所调用的函数指针
/**
* Returns the function pointer that would be called if a
* particular message were sent to an instance of a class.
*
* @param cls The class you want to inspect.
* @param name A selector.
*
* @return The function pointer that would be called if \c [object name] were called
* with an instance of the class, or \c NULL if \e cls is \c Nil.
*
* @note \c class_getMethodImplementation may be faster than \c method_getImplementation(class_getInstanceMethod(cls, name)).
* @note The function pointer returned may be a function internal to the runtime instead of
* an actual method implementation. For example, if instances of the class do not respond to
* the selector, the function pointer returned will be part of the runtime's message forwarding machinery.
*/
OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_respondsToSelector(Class cls,SEL sel)
查看 类中有没有这个方法
/**
* Returns a Boolean value that indicates whether instances of a class respond to a particular selector.
*
* @param cls The class you want to inspect.
* @param sel A selector.
*
* @return \c YES if instances of the class respond to the selector, otherwise \c NO.
*
* @note You should usually use \c NSObject's \c respondsToSelector: or \c instancesRespondToSelector:
* methods instead of this function.
*/
OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_copyMethodList
获取类的方法列表
/**
* 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, unsigned int *outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
代码 例子
unsigned int count = 0;
获取所有的方法数组
Method *dd = class_copyMethodList([dog class], &count);
for(int i=0;i<count;i++)
{
Method mmm = dd[i];
根据 Method获取SEL
SEL seee = method_getName(mmm);
根据SEL获取方法名字
const char *str = sel_getName(seee);
printf("---%s---\n",str);
}
*class_conformsToProtocol(Class cls,Protocol protocol)
看某个类是否遵守某个协议( @note You should usually use NSObject's conformsToProtocol: method instead of this function. )
/**
* Returns a Boolean value that indicates whether a class conforms to a given protocol.
*
* @param cls The class you want to inspect.
* @param protocol A protocol.
*
* @return YES if cls conforms to protocol, otherwise NO.
*
*
*/
OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_copyProtocolList
这个类所遵守的所有的协议
/**
* 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, unsigned int *outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
*class_getProperty(Class cls,const char name)
根据名字返回类中的声明的一个属性
/**
* Returns a property with a given name of a given class.
*
* @param cls The class you want to inspect.
* @param name The name of the property you want to inspect.
*
* @return A pointer of type \c objc_property_t describing the property, or
* \c NULL if the class does not declare a property with that name,
* or \c NULL if \e cls is \c Nil.
*/
OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
class_getProperty
class_copyPropertyList
/**
* Returns a property with a given name of a given class.
*
* @param cls The class you want to inspect.
* @param name The name of the property you want to inspect.
*
* @return A pointer of type \c objc_property_t describing the property, or
* \c NULL if the class does not declare a property with that name,
* or \c NULL if \e cls is \c Nil.
*/
OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
/**
* Describes the properties declared by a class.
*
* @param cls The class you want to inspect.
* @param outCount On return, contains the length of the returned array.
* If \e outCount is \c NULL, the length is not returned.
*
* @return An array of pointers of type \c objc_property_t describing the properties
* declared by the class. Any properties declared by superclasses are not included.
* The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().
*
* If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0.
*/
OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
代码实例
unsigned int coutn =0;
objc_property_t *das = class_copyPropertyList([person class], &coutn);
NSLog(@"==%d\n",coutn);
class_getIvarLayout
/**
* Returns a description of the \c Ivar layout for a given class.
*
* @param cls The class to inspect.
*
* @return A description of the \c Ivar layout for \e cls.
*/
OBJC_EXPORT const uint8_t *class_getIvarLayout(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
*class_addMethod(Class cls,SEL name,IMP imp,const char types)
给 类增加 一个实例方法
/**
* 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,
const char *types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
代码例子
person *ss = [[person alloc]init];
SEL 参数随便起名字 。他只是一种标志 Method的标志 。
IMP 函数指针 。
IMP指针函数的定义 正如下面定义的函数一样 一点参数必须是id self ,第二个参事是SEL _cmd
从第三个参数开始 是函数的参数
添加实例方法的最后一个参数是描述函数指针参数的 一个const char *
v代表 void
@ 代表对象id
:代表SEL
@代表对象NSString
BOOL dd = class_addMethod([person class], @selector(zhangwenyong), (IMP)mydd, "v@:@");
[ss performSelector:@selector(zhangwenyong) withObject:@"好的天简好课方"];
void mydd(id self,SEL _cmd,NSString *str)
{
NSLog(@"%@",str);
}
给类添加方法 是可行的 给类动态的添加方法 。 给类动态的添加方法
*class_replaceMethod(class cls,SEL name,IMP imp, const char type)
替换类的方法
/**
* Replaces the implementation of a method for a given class.
*
* @param cls The class you want to modify.
* @param name A selector that identifies the method whose implementation you want to replace.
* @param imp The new implementation for the method identified by name for the class identified by cls.
* @param types An array of characters that describe the types of the arguments to the method.
* Since the function must take at least two arguments—self and _cmd, the second and third characters
* must be “@:” (the first character is the return type).
*
* @return The previous implementation of the method identified by \e name for the class identified by \e cls.
*
* @note This function behaves in two different ways:
* - If the method identified by \e name does not yet exist, it is added as if \c class_addMethod were called.
* The type encoding specified by \e types is used as given.
* - If the method identified by \e name does exist, its \c IMP is replaced as if \c method_setImplementation were called.
* The type encoding specified by \e types is ignored.
*/
OBJC_EXPORT IMP class_replaceMethod(Class cls, SEL name, IMP imp,
const char *types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
替换类的方法
代码实例
void shangzhan(id self,SEL _cmd)
{
NSLog(@"替换的方法");
}
class_replaceMethod([person class], @selector(personaaa), (IMP)shangzhan, "v@:");
person *pd =[[person alloc]init];
[pd personaaa];
类的方法的替换 。这是类的方法 的替换 这是类的方法的替换
class_addIvar
给类增加属性 。给类增加属性 。给类增加属性 给类增加属性 给类增加属性
/**
* 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.
* 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, const char *name, size_t size,
uint8_t alignment, const char *types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
分割点
Adding Classes
objc_allocateClassPair
这个方法用于生成 一个类 。这个方法 用于生成一个类 。
这个方法 用于生成 一个类
/**
* Creates a new class and metaclass.
*
* @param superclass The class to use as the new class's superclass, or \c Nil to create a new root class.
* @param name The string to use as the new class's name. The string will be copied.
* @param extraBytes The number of bytes to allocate for indexed ivars at the end of
* the class and metaclass objects. This should usually be \c 0.
*
* @return The new class, or Nil if the class could not be created (for example, the desired name is already in use).
*
* @note You can get a pointer to the new metaclass by calling \c object_getClass(newClass).
* @note To create a new class, start by calling \c objc_allocateClassPair.
* Then set the class's attributes with functions like \c class_addMethod and \c class_addIvar.
* When you are done building the class, call \c objc_registerClassPair. The new class is now ready for use.
* @note Instance methods and instance variables should be added to the class itself.
* Class methods should be added to the metaclass.
*/
OBJC_EXPORT Class objc_allocateClassPair(Class superclass, const char *name,
size_t extraBytes)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
objc_registerClassPair(Class cls)
注册这个类
/**
* Registers a class that was allocated using \c objc_allocateClassPair.
*
* @param cls The class you want to register.
*/
OBJC_EXPORT void objc_registerClassPair(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
objc_disposeClassPair(Class cls)
销毁这个类
/**
* Destroy a class and its associated metaclass.
*
* @param cls The class to be destroyed. It must have been allocated with
* \c objc_allocateClassPair
*
* @warning Do not call if instances of this class or a subclass exist.
*/
OBJC_EXPORT void objc_disposeClassPair(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
网友评论