详解Objective-C的meta-class(1)
- UID
- 1066743
|
详解Objective-C的meta-class(1)
在运行时创建类
以下代码演示运行时创建一个NSError的子类,同时添加一个实例方法给它:
Class newClass =
objc_allocateClassPair([NSError class], "RuntimeErrorSubclass", 0);
class_addMethod(newClass, @selector(report), (IMP)ReportFunction, "v@:");
objc_registerClassPair(newClass);
函数ReportFunction就是添加的实例方法的具体实现,如下:
void ReportFunction(id self, SEL _cmd)
{
NSLog(@"This object is %p.",self);
NSLog(@"Class is %@, and super is %@.",[self class],[self superclass]);
Class currentClass = [self class];
for( int i = 1; i < 5; ++i )
{
NSLog(@"Following the isa pointer %d times gives %p",i,currentClass);
currentClass = object_getClass(currentClass);
}
NSLog(@"NSObject's class is %p", [NSObject class]);
NSLog(@"NSObject's meta class is %p",object_getClass([NSObject class]));
}
看起来一切都很简单,运行时创建类只需要三步:
1、为"class pair"分配空间(使用objc_allocateClassPair).
2、为创建的类添加方法和成员(上例使用class_addMethod添加了一个方法)。
3、注册你创建的这个类,使其可用(使用objc_registerClassPair)。
估计读者马上就要问:什么是“class pair"? objc_allocateClassPair只返回一个值:Class。那么pair的另一半在哪里呢?
是的,估计你已经猜到了这个另一半就是meta-class,也就是这篇短文的标题,但是要解释清楚它是什么,为什么需要它,还需要交代下OC的对象与类的相关背景。
一个数据结构何以成为一个对象?
每个对象都会有一个它所属的类。这是面向对象的基本概念,但是在OC中,这对所有数据结构有效。任何数据结构,只要在恰当的位置具有一个指针指向一个class,那么,它都可以被认为是一个对象。
在OC中,一个对象所属于哪个类,是由它的isa指针指向的。这个isa指针指向这个对象所属的class。
实际上,OC中对象的定义是如下的样子:
typedef struct objc_object {
Class isa;
}*id;
这个定义表明:任何以一个指向Class的指针作为首个成员的数据结构都可以被认为是一个objc_object.
最重要的特性就是,你可以向OC中的任何对象发送消息,如下这样:
【@”stringValue" writeToFile"/file.txt atomically:YES encoding: NSUTF8StringEncoding error:NULL];
运行原理就是,当你向一个OC对象发送消息时(上文的@“stringValue”),运行时库会根据对象的isa指针找到这个对象所属的类(上文为例,会找到NSCFString类).这个类会包含一个所有实例方法的列表及一个指向superclass的指针以便可以找到父类的实例方法。运行时库会在类的方法列表以及父类(们)的方法列表中寻找符合这个selector(上文为例,这个selector是"writeToFile:atomically:encoding:error")的方法。找到后即运行这个方法。关键点就是类要定义这个你发送给对象的消息。 |
|
|
|
|
|