深入浅出Cocoa教程.pdf

所需积分/C币:19 2016-09-26 10:59:28 5.17MB PDF
收藏 收藏
举报

深入浅出Cocoa教程
飘飘白云的《深入浅出 Cocoa教程〉 [深入浅出 Cocoa]之类与对象 罗朝辉(htp:/blogcsdn.com/kesalin) CC许可,转载请注明出处 最近打算写一些ObjC中比较底层的东西,尤其是 runtime相关的。苹果己经将 objc runtime代码开 源了,我们可以从:http://opensource.applecom/sourcelobic/obic4-493.9/runtime浏览源代 码,或点此下载源代码 从哪里入手呢?那当然是最基本的类与对象。与C++相比,ObjC中的类与对象结构要简洁与一致得多(参 考《深度探索C++对象模型》,你就知道C+十中类与村象结构旳复)。本文将详细讲解ObjC中类与 对象的结构,下回将讲如何在 runtime时操作类。 我们可以在/us/ include/objc/ objc. h和 runtime. h中找到对 class与 object的定义: typedef struct objc_class Class; ypedef struct objc_object i Class isa; Cass是一个objc_cass结构类型的指针;而id(任意对象)是一个objc_ object结构类型的指针, 其第一个成员是一个 objc_class结构类型的指针。注意这里有一关键的引中解读:内存布局以一个 ob ic class指针为开始的所有东东都可以当做一个 object来对待!那 objc class又是怎样一个结 构体呢?且看 struct objc class struct objc class isa struct objc_class super_class const chark name long version; long I nfo long instance size; struct objc_ivar_list* ivars; struct objc_method_ list ** methodIsts struct objc cache* cache; struct objc_protocol_ list* protocols objc_class结构体的各成员介绍如下: sa:是一个 objc class类型的指针,看到这里,想起我前面的引中解读了没?内存布局以一个 objc class指 针为开始的所有东东都可以当做一个 object来对待!这就是说obj_cass或者说类其实也可以当做一个 3/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 bjc_ object对象来对待!对象是对象,类也是对象,是不是有点混淆?别急,ObjC发明(or重用)了 个术语来区分这两种不同的对象:类对象( class object)与实例对象( instance object)。OK,名 称混淆的问题解决,下面我将使用这两个术语来区分不同的对象,而使用"对象“这一术语来泛指所有的对 象。ObjC还对类对象与实例对象屮的isa所指向的类结构作了不同的命名:类对象中的isa指向类结构 被称作 metaclass, metaclass存储类的 static类成员变量与 static类成员方法(+开头的方法);实 例对象中的isa指向类结杓称作 class(普通的), class结杓存储类的普通成员变量与普通成员方法(- 开头的方法)。 super_ class:一看就明白,指向该类的父类呗!如果该类已经是最顶层的根类(如 NSobject或 NSProxy),那么 super_class就为NULL 好,先中新一下其类结构成员的介绍,让我们哐清一下在銖承层次中,子类,父类,根类(这些都是普 通cass)以及其对应的 metaclass的isa与 super_ class之间关系 规则一:类的实例对象的isa指向该类:该类的isa指向该类的 metaclass; 烑则一:类的 super class指向其父类,如果该类为棖类则值为NUL 规则三: metaclass的isa指向根 metaclass,如果该 metaclass是根 metaclass则指向自身 规则四: metaclass的 super_class指向父 metaclass,如果该 metaclass是根 metaclass则指间 该 metaclass对应的类 好吧,文字总是那么乏力,有图有真相! superclass ni Root class (meta) Root class (class) Instance of Root class Root class uperclass (meta Superclass (class) Instance of Superclass Superclass Subclass ( meta Subclass (class) Instance of Subclass Subclass < instance object, class, metaclass的isa与 super_ class关系图> 4/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 那么 class与 metaclass有什么区别呢? class是 instance object的类类型。当我们向实例对象发送消息(实例方法)时,我们在该实例对象的 caSs结构的 methodists中去查找响应的函数,如果没找到匹配的响应函数则在该cass的父类中的 methodists去査找(查找链为上图的中间那一排)。如下面的代码中,向str实例对象发送 lowercase String消息,会在 NSString类结构的 methodists中去查找 lowercase String的响应 数 NSString str; [str lowercasestring] metaclass是 class object的类类型。当我们向类对象发送消息(类方法)时,我们在该类对象的 metaclass结构的 methodists中去查找响应的函数,如果没有找到匹配的响应函数则在该 metaclass的父类中的 methodists去查找(查找链为上图的最右边那一排)。如下面的代码中,向 NSString类对象发送 string With String消息,会在 NSString的 metaclass类结构的 methodists中去查找 string With string的响应函数 [NSString string With String: @ str"]; 好,至此我们明白了类的结构层次,让我们接着看类结构中的共他成员。 name:一个C宇符串,指示类的名称。我们可以在运行期,通过这个名称查找到该类(通过:id objc_ getclasst( const char* a classname))或该类的 metaclass( id objc_ getMetaClass( const char *aClassName)) version:类的版本信息,默认初始化为0。我们可以在运行期对其进行修改( class setversion)戌获 取( class getVersion)。 nfo:供运行期使用的一些位标识。有如下一些位掩码: CLS CLASS(0x1L)表示该类为普通cass,其中包含实例方法和变量; CLS_META(0×2L)表示该类为 metaclass,其屮包含类方法 CLS_ INITIALIZED(0×4L)表示该类已经被运行期初始化了,这个标识位只被 objc_addClass所设置 CLS POSING(0x8L)表示该类被pose成其他的类;( poseclass在ObjC2.0中被废齐了); CLs_ MAPPED(010L)为ObjC运行期所使用 CLS FLUSH CACHE(0×20L)为Objc运行期所使用 CLS GROW_ CACHE(0X40L)为ObjC运行期所使用 CLS NEED BIND(0x80L)为ObjC运行期所使用 CLS METHOD ARRAY(0x100L)该标志位指示 methodists是指向一个 objc method list还是 一个包含objc_ method ist指针的数组 instance si|ze:该类的实例变量大小(包括从父类继承下来的实例变量) vars:指向 objc_ ivar_list的指针,存储每个实例变量的内存地址,如果该类没有任何实例变量则为 NULL 5/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 methodists:与info的一些标志位有关,CLS_ METHOD_ ARRAY标识位决定其指向的东西(是指 向单个 objc method_is还是一个 objc method list指针数组),如果info设置了CLS_ CLASS 则objc_ method list存储实例方法,如果设置的是CLS_META则存储类方法 cache:指向 objc cache的指针,用来缓存最近使用的方法,以提高效率 protocols:指向objc_ protocol list的指针,存储该类声明要遵守的正式协议。 总结 ObjC为每个类的定义生成两个 objc class,一个即普通的 class,另一个即 metaclass。我们可以在 运行期创建这两个objc_ class数据结构,然后使用 objc_addClass动怂地创建新的类定义。这个够动 态够强大的吧?下回讲演示如何在运行期动态创建新类。 6/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 [深入浅出 Cocoa]之动态创建类 罗朝辉(htp;/ blog. csdn.net,/ kesalin/) CC许可,转载请注明出处 在前文《深入浅出 Cocoa之类与对象》一文中,我已经详细介绍了ObjC中的 Class与 object的概念, 今天我们来如何在运行 时 动态创建类。下面这个函数就是应用前面讲到的 Class, Meta class的概念,在运行时动态创建一个类 这个函数来自 (Inside mac os x-The objective-C Programming Language》 #import <objcobjc.h> # import sobjc/runtime.h> BOOL Create ClassDefinition( const char x name, const char x superclassName) struct objc_class* meta_class struct objc_class super_class struct objc class new_ class; struct objc_class x root_class; va list args ∥/确俣父类存在 super- class =(struct objc_class objc_ lookUpClass (superclassName); if(super_class = nil) return No: /确保要创建的类不存在 if (objc_lookUpClass (name)!= nil) return no 查找 root class,因为 meta class的isa指向 root class的 meta class root class super class while( root_class->super_class I= nil) root_class root_class->super_class 7/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 ∥/为cass及其 meta class分配内存 new_class calloc( 2, sizeof(struct objc_class)): meta class &new_class[11 ∥/设置cass new class->isa= meta class new class->info CLS CLASS meta class->info CLS META ∥/拷从类名字,这里为∫提高效率,让cass与 meta class都指向同一个类名字符串 new_ class->name = malloc (strlen(name)+ 1) strcpy((char )new_class->name, name) meta class->name new class->name ∥/分配并置空 method lists,我们可以在之后使用 class add Methods回类中增加方法 new_class->method Lists calloc( 1, sizeof(struct objc_method_list *)) meta class->methodIsts= calloc( 1, sizeof(struct objc method list*)); /将类加入到继承体系中去: /1,设置类的 super class ∥/2,设置 meta class的 super class /3,设置 meta class的isa new class->super class super cla neta class->super class super_ class->isa meta_class-isa=(void *)root_class->isa ∥/最后,将cass注册到运行时系统中 objc_addClass( new_class ) return YeS 如果要在代码中使用运行时相关的函数,我们需要导入 libobjc. dylib,并导入相关的头文件(比如这里的 runtime.h)。 在前文中总结到ObC为每个类的定义生成两个 objc_class,个目普通的cas,另一个即 metaclass。我们 可以在运行期创建这两个objc_dass数据结构,然后使用 objc addclass动态地创建新的类定义。",这在上面 的代码中就体现出米了: new class和meta_cass就是新类所必须的两个 objc_class.。其他的代码就 不解释了,注释以及代码是以自明了。 在实际的运用中,我们使用ObjC运行时函数来动态创建类 Class objc_allocateClassPair( Class superclass, const char *name, size t extra Bytes); 8/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 譬如 # import <objc/objc.h> import <objc/runtime. h> void ReportFunction(id self sEL_cmd) NSLog(@>>This object is op, self) NSLog(@>> Class is %/@, and super is %o@. [self class] [self superclass]) Class prev Class= NULLI int count 1 for(class currentClass [self class ] current class ++count) prevclass currentclass; NSLog(@">> Following the isa pointer %/od times gives %op" count currentclass) currentClass object_getClass(currentClass if (prevclass = currentclass) break } NSLog(@">> NSObject s class is%op,[NSObject class]); NSLog(@">> NSobject s meta class is %op, object getclass([Nsobject class]); int main (int argc, const char* argv]) @autoreleasepool Class new Class objc_allocate ClassPair([NSString class],"NSStringSubclass",0); class_addMethod (new Class, @selector (report),(IMPReportFunction, v@: objc_registerClass Pair(new class) id instanceOfNew Class =[[new Class alloc] init [instanceOfNew Class performselector: @selector (report) [instanceOfNew Class release return 0 在上面的代码中,我们创建继承自 NSString的子类 NSStringSubclass,然后向其中添加方法 report 9/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/ 飘飘白云的《深入浅出 Cocoa教程〉 并在运行时系统中注册,这样我们就可以使用这个新类了。在这里使用 performSelector来向新类的对 象发送消息,可以避饣编译警告信息(因为我们并没有声眀该类及其可响应的消息)。 执行结果为: > This object is 0x 100114710 > Class is NSString Subclass, and super is Nsstring > Following the isa pointer 1 times gives 0x100114410 > Following the isa pointer 2 times gives 0x 100114560 >>Following the isa pointer 3 times gives OX7fff7e257b50 > NSObject's class is 0x7fff7e257b78 NSobject's meta class is Ox7fff7e257b50 根据前文中的类关系图,我们不难从执行结中分析出 NSString Subclass的内部类结构: 1,对象的地址为:0x100114710 2,cass的地址为:0×100114410 3, meta class的地址为:0×100114560 4, meta class的 class地址为:0xfe257b50(也是 NSobject的 meta class) 5, NSobject的 meta class的 meta class是其自身 10/163 飘飘白云(罗朝辉):http://blog.csdn.net/kesalin微博交流:http://weibo.com/kesalin/

...展开详情
试读 127P 深入浅出Cocoa教程.pdf
立即下载 低至0.43元/次 身份认证VIP会员低至7折
抢沙发
一个资源只可评论一次,评论内容不能少于5个字
上传资源赚积分or赚钱
最新推荐
深入浅出Cocoa教程.pdf 19积分/C币 立即下载
1/127
深入浅出Cocoa教程.pdf第1页
深入浅出Cocoa教程.pdf第2页
深入浅出Cocoa教程.pdf第3页
深入浅出Cocoa教程.pdf第4页
深入浅出Cocoa教程.pdf第5页
深入浅出Cocoa教程.pdf第6页
深入浅出Cocoa教程.pdf第7页
深入浅出Cocoa教程.pdf第8页
深入浅出Cocoa教程.pdf第9页
深入浅出Cocoa教程.pdf第10页
深入浅出Cocoa教程.pdf第11页
深入浅出Cocoa教程.pdf第12页
深入浅出Cocoa教程.pdf第13页
深入浅出Cocoa教程.pdf第14页
深入浅出Cocoa教程.pdf第15页
深入浅出Cocoa教程.pdf第16页
深入浅出Cocoa教程.pdf第17页
深入浅出Cocoa教程.pdf第18页
深入浅出Cocoa教程.pdf第19页
深入浅出Cocoa教程.pdf第20页

试读结束, 可继续阅读

19积分/C币 立即下载 >