- 浏览: 13748361 次
- 性别:
- 来自: 洛杉矶
文章分类
- 全部博客 (1994)
- Php / Pear / Mysql / Node.js (378)
- Javascript /Jquery / Bootstrap / Web (435)
- Phone / IOS / Objective-C / Swift (137)
- Ubuntu / Mac / Github / Aptana / Nginx / Shell / Linux (335)
- Perl / Koha / Ruby / Markdown (8)
- Java / Jsp (12)
- Python 2 / Wxpython (25)
- Codeigniter / CakePHP (32)
- Div / Css / XML / HTML5 (179)
- WP / Joomla! / Magento / Shopify / Drupal / Moodle / Zimbra (275)
- Apache / VPN / Software (31)
- AS3.0/2.0 / Flex / Flash (45)
- Smarty (6)
- SEO (24)
- Google / Facebook / Pinterest / SNS (80)
- Tools (22)
最新评论
-
1455975567:
xuezhongyu01 写道wocan23 写道我想问下那个 ...
Mysql: LBS实现查找附近的人 (两经纬度之间的距离) -
xuezhongyu01:
wocan23 写道我想问下那个111.1是怎么得来的我也看不 ...
Mysql: LBS实现查找附近的人 (两经纬度之间的距离) -
18335864773:
试试 pageoffice 在线打开 PDF 文件吧. pag ...
jquery在线预览PDF文件,打开PDF文件 -
青春依旧:
opacity: 0.5; 个人喜欢这种方式!关于其他css特 ...
css透明度的设置 (兼容所有浏览器) -
July01:
推荐用StratoIO打印控件,浏览器和系统的兼容性都很好,而 ...
搞定网页打印自动分页问题
6,NSObject的奥秘
本系列讲座有着很强的前后相关性,如果你是第一次阅读本篇文章,为了更好的理解本章内容,笔者建议你最好从本系列讲座的第1章开始阅读,请点击这里 。
在上一章里 面,笔者向大家介绍了在Objective-C里面的几个非常重要的概念, 简单的说就是SEL,Class和IMP。我们知道Objective-C是C语言的扩展,有了这3个概念还有我们以前讲过的继承和封装的概 念,Objective-C发生了翻天覆地的变化,既兼容C语言的高效特性又实现了面向对象的功能。
Objective-C从本质上来说,还是C语言的。那么内部究竟是怎样实现SEL,Class和IMP,还有封装和继承的?为了解答这个问题,笔者决定在本章向大家概要的介绍一下Objective-C的最主要的一个类,NSObject。
不过说实在话,如果同学们觉得本章的内容比较晦涩难懂的话,不阅读本章的内容丝毫不会对写程序产生任何不良的影响,但是如果掌握了本章的内容的话,对加深对Objective-C的理解,对于今后笔者将要讲述的内容而言,将会是一个极大的促进。
6.1,本章程序的执行结果
在本章里面,我们将要继续使用我们在前面几章已经构筑好的类Cattle和Bull。由于在现在的Xcode版本里面,把一些重要的东西比如说Class的原型定义都放到了LIB文件里面,所以这些东西的具体的定义,对于我们来说是不可见的。
我们首先把第4章的代码 打开,然后打开“Cattle.h” 文件,把鼠标移动到“NSObject”上面,单击鼠标右键,在弹出菜单里面选择“Jump to Definition”。然后会弹出一个小菜单,我们选择“interface NSObject” 。我们可以看到如下代码
@interface NSObject <NSObject> { Class isa;
我们知道了,所谓的NSObject里面只有一个变量,就是Class类型的isa。isa的英文的意思就是is a pointer的意思。也就是说NSObject里面只有一个实例变量isa。好的,我们需要知道Class是一个什么东西,我们把鼠标移动到 “Class”上面,单击鼠标右键,在弹出菜单里面选择“Jump to Definition”,我们看到了如下的代码:
typedef struct objc_class *Class; typedef struct objc_object { Class isa; } *id; ...
我们在这里知道了,Class实际上是一个objc_class 的指针类型,我们把鼠标移动到“objc_class ”上面,单击鼠标右键,在弹出菜单里面选择“Jump to Definition”,发现我们还是在这个窗口里面,Xcode并没有把我们带到objc_class 的定义去,所以我们无从知道objc_class 内部究竟是一个什么样的东西。
笔者顺便提一下,大家也许注意到了id的定义,id实际上是objc_object结构的一个指针,里面只有一个元素那就是Class。那么根据上面我们看到的,所谓的id就是 objc_class 的指针的指针。让我们回忆一下下面的代码:
这句话是在初始化和实例话cattle对象,这个过程,实际上可以理解为,runtime为我们初始化好了Class的指针,并且把这个指针返回给我们。我们初始化对象完成了之后,实际上我们得到的对象就是一个指向这个对象的Class指针。
让我们在回过头来说说这个神秘的Class,我们无法在Xcode里面看到Class也就是objc_class 的 定义。庆幸的是这部分的定义是GCC代码,是开源的。笔者下载了开源的代码之后,把开源的代码作了一些小小的调整,然后把Class的定义等等放到了我们 的工程文件里面去,通过类型转化之后,我们终于可以看到Class,SEL,还有isa等等过去对我们来说比较“神秘”的东西的真正面目。
我们在前面几章里面在每一个章的第一节里面都要介绍一下本章程序执行结果的屏幕拷贝,本章也是一样,但是本章的执行结果非常简单。因为对于本章而言重点应该是放在对NSObject机制的理解上。
图6-1,本章程序运行结果
大家看到本章程序的运行结果的屏幕拷贝的时候,也许会觉得很无趣,因为单单从结果画面,我们没有发现任何令人感到很有兴趣的东西,相反,都是同学们 已经很熟悉的一些老面孔。但是本章所要讲述的东西也许是同学们在其他语言里面从来没有遇到过的东西,这些东西将会令人感到新鲜和激动。
6.2,实现步骤
第一步,按照我们在第2章所述的方法,新建一个项目,项目的名字叫做06-NSObject。如果你是第一次看本篇文章,请到这里 参看第二章的内容。
第二步,按照我们在第4章的4.2节的第二,三,四步所述的方法,把在第4章已经使用过的“Cattle.h”,“Cattle.m”,“Bull.h”还有“Bull.m” 导入本章的项目里面。如果你没有第4章的代码,请到这里 下载。如果你没有阅读第4章的内容,请参看这里 。
第三步,把鼠标移动到项目浏览器上面的“Source”上面,然后在弹出的菜单上面选择“Add”,然后在子菜单里面选择“New File”,然后在新建文件对话框的左侧最下面选择“Other”,然后在右侧窗口选择“Empty File”,选择“Next”,在“New File”对话框里面的“File Name”栏内输入“MyNSObject.h”。然后输入(或者是拷贝也可以,因为这是C的代码,如果你很熟悉C语言的话,可以拷贝一下节省时间)如下 代码:
#include <stddef.h> typedef const struct objc_selector { void *sel_id; const char *sel_types; } *MySEL; typedef struct my_objc_object { struct my_objc_class* class_pointer; } *myId; typedef myId (*MyIMP)(myId, MySEL, ); typedef char *STR; /* String alias */ typedef struct my_objc_class *MetaClass; typedef struct my_objc_class *MyClass; struct my_objc_class { MetaClass class_pointer; struct my_objc_class* super_class; const char* name; long version; unsigned long info; long instance_size; struct objc_ivar_list* ivars; struct objc_method_list* methods; struct sarray * dtable; struct my_objc_class* subclass_list; struct my_objc_class* sibling_class; struct objc_protocol_list *protocols; void* gc_object_type; }; typedef struct objc_protocol { struct my_objc_class* class_pointer; char *protocol_name; struct objc_protocol_list *protocol_list; struct objc_method_description_list *instance_methods, *class_methods; } Protocol; typedef void* retval_t; typedef void(*apply_t)(void); typedef union arglist { char *arg_ptr; char arg_regs[sizeof (char*)]; } *arglist_t; typedef struct objc_ivar* Ivar_t; typedef struct objc_ivar_list { int ivar_count; struct objc_ivar { const char* ivar_name; const char* ivar_type; int ivar_offset; } ivar_list[1]; } IvarList, *IvarList_t; typedef struct objc_method { MySEL method_name; const char* method_types; MyIMP method_imp; } Method, *Method_t; typedef struct objc_method_list { struct objc_method_list* method_next; int method_count; Method method_list[1]; } MethodList, *MethodList_t; struct objc_protocol_list { struct objc_protocol_list *next; size_t count; Protocol *list[1]; };
第四步,打开06-NSObject.m文件,输入如下代码并且保存
#import <Foundation/Foundation.h> #import "Cattle.h" #import "Bull.h" #import "MyNSObject.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; id cattle = [Cattle new]; id redBull = [Bull new]; SEL setLegsCount_SEL = @selector(setLegsCount:); IMP cattle_setLegsCount_IMP = [cattle methodForSelector:setLegsCount_SEL]; IMP redBull_setLegsCount_IMP = [redBull methodForSelector:setLegsCount_SEL]; [cattle setLegsCount:4]; [redBull setLegsCount:4]; [redBull setSkinColor:@"red"]; Class cattle_class = cattle->isa; MyClass my_cattle_class = cattle->isa; SEL say = @selector(saySomething); IMP cattle_sayFunc = [cattle methodForSelector:say]; cattle_sayFunc(cattle, say); Class redBull_class = redBull->isa; MyClass my_redBull_class = redBull->isa; IMP redBull_sayFunc = [redBull methodForSelector:say]; redBull_sayFunc(redBull, say); [pool drain]; return 0; }
第五步,在06-NSObject.m文件的窗口的“[pool drain]; ”代码的左侧单击一下窗口的边框,确认一下是否出现一个蓝色的小棒棒,如果有的话那么断点被选择好了。如图6-2所示
图6-2,选择执行断点
第六步,选择Xcode上面的菜单的“Run”,然后选择“Debuger” ,在Debuger窗口里面选择“Build and Go”。
好的,大家就停在这里,不要做其他的操作,我们把程序中断在程序几乎执行到最后的断点上,我们将要通过Debuger来看看Objective-C内部究竟发生了什么样的奇妙的魔法。
注意 在从编译到执行的过程当中,会出现一些警告。由于本章程序指示用来阐述一些NSObject内部的东西,所以请忽略掉这些警告。当然,我们在写自己的程序的时候,编译产生的警告一般是不能被忽略的。
6.3,超类方法的调用
我们现在打开“06-NSObject.m”文件,发现下面的代码:
SEL setLegsCount_SEL = @selector(setLegsCount:); IMP cattle_setLegsCount_IMP = [cattle methodForSelector:setLegsCount_SEL]; IMP redBull_setLegsCount_IMP = [redBull methodForSelector:setLegsCount_SEL];
这一段代码,对同学们来说不是什么新鲜的内容了,我们在第5章里面已经讲过,这个是SEL和IMP的概念。我们在这里取得了cattle对象和redBull对象的setLegsCount:的函数指针。
如果大家现在已经不在Debuger里面的话,那么请选择Xcode菜单里面的,“Run”然后选择“Debuger” 。
我们注意到在Debuger里面,cattle_setLegsCount_IMP 的地址和redBull_setLegsCount_IMP 是完全一样的,如图6-3所示:
图6-3,cattle_setLegsCount_IMP 和redBull_setLegsCount_IMP 的地址。
注意 由于环境和执行的时候的内存情况不同,所以同学们的电脑上显示的地址的数值可能和图6-3的数值不一样。
cattle_setLegsCount_IMP 和redBull_setLegsCount_IMP 的地址完全一样,说明他们使用的是相同的代码段。这种结果是怎样产生的呢?大家请打开“MyNSObject.h”,参照下列代码:
struct my_objc_class { MetaClass class_pointer; struct my_objc_class* super_class; const char* name; long version; unsigned long info; long instance_size; struct objc_ivar_list* ivars; struct objc_method_list* methods; struct sarray * dtable; struct my_objc_class* subclass_list; struct my_objc_class* sibling_class; struct objc_protocol_list *protocols; void* gc_object_type; };
笔者在这里把开源代码的名字的定义加上了“my_”前缀,仅仅是为了区分一下。“MyNSObject.h”里面的代码问题很多,笔者从来没有也不会在实际的代码里面使用这段代码,使用这些代码的主要目的是为了向大家讲解概念,请大家忽略掉代码里面的种种问题。
我们注意到这里的methods 变量,里面包存的就是类的方法名字(SEL)定义,方法的指针地址(IMP)。当我们执行
__inline__ IMP objc_msg_lookup(id receiver, SEL op) { if(receiver) return sarray_get(receiver->class_pointer->dtable, (sidx)op); else return nil_method;
好的,现在我们的cattle_setLegsCount_IMP没有问题了,那么 redBull_setLegsCount_IMP 怎 么办?在Bull类里面我们并没有定义实例方法setLegsCount:,所以在Bull的Class里面,runtime难道找不到 setLegsCount:么?答案是,是的runtime直接找不到,因为我们在Bull类里面根本就没有定义setLegsCount:。
但是,从结果上来看很明显runtime聪明的找到了setLegsCount:的地址,runtime是怎样找到的?答案就在:
在自己的类里面没有找到的话,runtime会去Bull类的超类cattle里面去寻找,庆幸的是它成功的在cattle类里面runtime找到了setLegsCount:的执行地址入口,所以我们得到了redBull_setLegsCount_IMP 。 redBull_setLegsCount_IMP 和cattle_setLegsCount_IMP 都是在Cattle类里面定义的,所以他们的代码的地址也是完全一样的。
我们现在假设,如果runtime在cattle里面也找不到setLegsCount:呢?没有关系,cattle里面也有超类的,那就是 NSObject。所以runtime会去NSObject里面寻找。当然,NSObject不会神奇到可以预测我们要定义setLegsCount:所 以runtime是找不到的。
在这个时候,runtime 并没有放弃最后的努力,再没有找到对应的方法的时候,runtime会向对象发送一个forwardInvocation:的消息,并且把原始的消息以及 消息的参数打成一个NSInvocation的一个对象里面,作为forwardInvocation:的唯一的参数。 forwardInvocation:本身是在NSObject里面定义的,如果你需要重载这个函数的话,那么任何试图向你的类发送一个没有定义的消息的 话,你都可以在forwardInvocation:里面捕捉到,并且把消息送到某一个安全的地方,从而避免了系统报错。
笔者没有在本章代码中重写forwardInvocation:,但是在重写forwardInvocation:的时候一定要注意避免消息的循环 发送。比如说,同学们在A类对象的forwardInvocation里面,把A类不能响应的消息以及消息的参数发给B类的对象;同时在B类的 forwardInvocation里面把B类不能响应的消息发给A类的时候,容易形成死循环。当然一个人写代码的时候不容易出现这个问题,当你在一个工 作小组里面做的时候,如果你重写forwardInvocation:的时候,需要和小组的其他人达成共识,从而避免循环调用。
6.4,重载方法的调用
让我们继续关注“06-NSObject.m”文件,请大家参考一下下面的代码:
Class cattle_class = cattle->isa; MyClass my_cattle_class = cattle->isa; SEL say = @selector(saySomething); IMP cattle_sayFunc = [cattle methodForSelector:say]; cattle_sayFunc(cattle, say); Class redBull_class = redBull->isa; MyClass my_redBull_class = redBull->isa; IMP redBull_sayFunc = [redBull methodForSelector:say]; redBull_sayFunc(redBull, say);
本节的内容和6.3节的内容比较类似,关于代码部分笔者认为就不需要解释了,如果同学们有所不熟悉的话,可以参考一下第5章的内容。
在我们的Cattle类和Bull类里面,都有saySometing这个实例方法。我们知道只要方法的定义相同,那么它们的SEL是完全一样的。 我们根据一个SEL say,在cattle和redBull对象里面找到了他们的函数指针。根据6.3节的讲述,我们知道当runtime接收到寻找方法的时候,会首先在这 个类里面寻找,寻找到了之后寻找的过程也就结束了,同时把这个方法的IMP返回给我们。所以,在上面的代码里面的cattle_sayFunc 和redBull_sayFunc 应该是不一样的,如图6-4所示:
图6-4, cattle_sayFunc 和redBull_sayFunc 的地址
6.5,超类和子类中的Class
在类进行内存分配的时候,对于一个类而言,runtime需要找到这个类的超类,然后把超类的Class的指针的地址赋值给isa里面的super_class 。所以,我们的cattle里面的Class应该和redBull里面的Class里面的super_class 应该是完全相同的,请参照图6-5:
图6-5, cattle里面的Class和redBull里面的Class里面的super_class
6.6,实例变量的内存分配的位置
我们先来回忆一下对象是怎样被创建的。创建对象的时候,类的内容需要被调入到内存当中我们称之为内存分配(Allocation),然后需要把实体变量进 行初始化(Initialization),当这些步骤都结束了之后,我们的类就被实例化了,我们把实例化完成的类叫做对象(Object)。
对于内存分配的过程,runtime需要知道分配多少内存还有各个实例变量的位置。我们回到“MyNSObject.h”,参照如下代码:
typedef struct objc_ivar* Ivar_t; typedef struct objc_ivar_list { int ivar_count; struct objc_ivar { const char* ivar_name; const char* ivar_type; int ivar_offset; } ivar_list[1]; } IvarList, *IvarList_t;
我们仔细看看第5行的ivar_name,顾名思义这个是实例变量的名字,第6行的ivar_type是实例变量的类型,第7行的 ivar_offset,这个就是位置的定义。runtime从类的isa里面取得了这些信息之后就知道了如何去分配内存。我们来看看图6-6:
图6-6,实例变量在内存中的位置
在cattle里面,我们看到了第一个实例变量是isa,第二个就是我们定义的legsCount。其中isa是超类的变量,legsCount是Cattle类的变量。我们可以看出来,总是把超类的变量放在前头,然后是子类的变量。
那么对于redBull而言是什么样子呢?我们来看看图6-7
图6-7,redBull里面的实例变量的位置
我们通过图6-7可以发现redBull的Class里面的skinColor的位置偏移是8,很明显,runtime为isa和legsCount预留了2个位置。
6.7本章总结
非常感谢大家!
在本章里面,笔者通过一个小小的“把戏”为同学们揭开了NSObject的神秘的面纱。本章的内容,虽然对理解Objective-C不是必需的,但是对以后的章节的内容的理解会有一个非常好的辅助作用,希望同学们花费一点点心思和时间阅读一下。
另外,笔者需要再次强调一下,由于笔者没有得到官方的正式的文档说明,所以不能保证本章的内容是完整而且准确的,本章内容仅供大家参考和娱乐,希望大家谅解。
来源:http://www.cnblogs.com/yaski/archive/2009/04/13/1434308.html
发表评论
-
手机firebug查看网页代码 How to View Website Source Codes on iPad / iPhone
2016-04-26 02:41 1173You’re using your iPad to br ... -
Android模拟器genymotion的安装和使用
2016-03-18 01:16 2534Genymotion概述 Genymotion是一套完整的 ... -
编码之道:取个好名字很重要
2015-10-14 05:19 1178代码就是程序员的孩子,给“孩子”取个好听的名字很重 ... -
Genymotion - 强大好用高性能的 Android 模拟器 (在电脑流畅运行APK安卓软件游戏的利器)
2015-06-05 13:34 7398随着 Android 系统的应用和游戏越来越丰富,甚至有 ... -
收集几个移动平台浏览器的User-Agent
2014-07-23 02:33 3034List of all Mobile Browsers ... -
常用浏览器修改User-Agent的方法
2014-06-28 02:58 10993之前有介绍收集的几个移动平台浏览器的User-Agent,以 ... -
更简洁的方式修改Chrome的User Agent,轻松体验移动版网络
2014-06-28 02:53 6952国庆节在家宅着,使用3g上网卡上网,和在公司上网不一样的是 ... -
3个检测浏览器User-Agent信息的网站
2014-06-28 02:52 2565刚刚在收集各个移动平台浏览器的User-Agent(参见这 ... -
根据移动设备屏幕像素密度,给予不同分辨率的图片
2014-06-26 00:52 2976在出现iphone4之前的相当长的时间内,网站开发人员 ... -
视网膜New iPad与普通分辨率iPad页面的兼容处理
2014-06-26 00:44 1352一、这是篇经验分享 ... -
iOS8开发-Swift编程
2014-06-25 00:45 1916课时列表 章节1:第一个Swift应用 ... -
Swift中文教程(二十三) 高级运算符
2014-06-25 00:43 831除了基本操作符中所讲的运算符,Swift还有许多复杂的高级 ... -
Swift中文教程(二十二) 泛型
2014-06-25 00:35 1076泛型代码可以让你写出根据自我需求定义、适用于任何类型的,灵 ... -
Swift中文教程(二十一) 协议
2014-06-24 05:25 1465Protocol(协议)用于统一方法和属性的名称,而不实现任 ... -
Swift中文教程(二十) 扩展
2014-06-24 00:47 739扩展就是向一个已有的类、结构体或枚举类型添加新功能(fun ... -
Swift中文教程(十九) 类型嵌套
2014-06-24 00:44 935枚举类型常被用于实现特定类或结构体的功能。也能够在有多种变量 ... -
Swift中文教程(十八) 类型检查
2014-06-24 00:41 782类型检查是一种检查类实例的方式,并且或者也是让实例作为它的 ... -
Swift中文教程(十七) 可选链
2014-06-17 05:11 909可选链(Optional Chaining)是一种可以请求 ... -
Swift中文教程(十六) 自动引用计数
2014-06-17 05:05 1295Swift使用自动引用计数(ARC)来管理应用程序的内存使 ... -
Swift中文教程(十五) 析构
2014-06-17 04:57 1041在一个类的实例被释放之前,析构函数会被调用。用关键字dei ...
相关推荐
### Objective-C 2.0 与 Cocoa Foundation:深入学习指南 #### 第 1 章:Objective-C 与 Cocoa Foundation 入门 ##### 1.1 Objective-C 的基础概述 Objective-C 是一种面向对象的编程语言,它是在 C 语言的基础上...
Objective-C 2.0是Apple开发的面向对象的编程语言,它是Cocoa和Cocoa Touch框架的基础。在Objective-C中,类方法(Class Methods)和私有方法(Private Methods)是两个重要的概念,它们对于理解和编写高效、安全的...
本教程将深入探讨Objective-C 2.0与Cocoa Foundation的结合,从经典的"Hello, World!"程序开始,逐步揭示这门语言的强大之处。 "Hello, World!"是所有编程旅程的传统起点,它展示了语言的基本语法和输出功能。在...
在Objective-C 2.0中,Cocoa Foundation是核心库之一,提供了大量用于构建应用程序的基本服务。本节将深入探讨Objective-C 2.0中的继承机制,以及如何在Cocoa Foundation框架下使用它。 ### 继承的概念 继承是面向...
Objective-C 2.0是Apple开发的面向对象的编程语言,它是Cocoa和Cocoa Touch框架的基础。在Objective-C中,对象的初始化和实例变量的作用域是编程中的关键概念,对于理解和创建健壮的iOS和macOS应用程序至关重要。 ...
《Objective-C 2.0程序设计》是一本关于MacOSX系统和iPhone平台下标准程序设计语言Objective-C 2.0的权威参考书。Objective-C是一种面向对象的编程语言,基于C语言设计而成,广泛用于OSX以及多种支持gcc编译器的操作...
《Effective Objective-C 2.0》是一本由Matt Galloway所著的关于Objective-C编程语言的书籍,主要面向开发iOS和OS X应用程序的开发者。这本书详细阐述了如何利用Objective-C 2.0的新特性和最佳实践来提高程序的效率...
Objective-C 2.0 运行时系统编程指南详细介绍了Objective-C语言的关键特性之一——运行时系统的工作原理。通过深入学习这些内容,开发者可以更好地理解Objective-C是如何在运行时解决各种问题的,从而有效地利用这些...
Objective-C 2.0 是苹果公司开发的一种面向对象的编程语言,它是基于C语言的,同时引入了Smalltalk的关键概念,如消息传递和动态类型。这个语言主要用于开发iOS和macOS平台的应用程序。《Objective-C 2.0 程序设计》...
Objective-C 2.0 是一种通用的面向对象的编程语言,它结合了C语言的基础特性和Smalltalk的对象模型。Objective-C 2.0 由 Apple Inc. 开发并维护,广泛应用于开发 Mac OS X 和 iOS 应用程序。 #### 二、Objective-C ...
### Objective-C 2.0程序设计相关知识点 #### 一、Objective-C语言基础 - **类与对象**:Objective-C是一种面向对象的语言,其核心概念是类和对象。类定义了对象的行为和属性,对象则是类的一个实例。本书第一章至...
### Objective-C 2.0 运行时系统编程指南 #### 概述 Objective-C是一种面向对象的编程语言,它以其独特的动态性而闻名。这种动态性体现在它能够尽可能地将决策过程推迟到运行时执行,而不是在编译或链接阶段。因此...
Objective-C 2.0 是一种通用、面向对象的编程语言,它结合了C语言的基础特性和Smalltalk的对象模型及动态特性。Objective-C 2.0 由 Apple Inc. 开发并维护,广泛应用于开发 macOS 和 iOS 应用程序。 #### 二、...
### Objective-C 2.0 运行时系统编程指南知识点详解 #### 概述 Objective-C 2.0 的运行时系统是该语言的核心组成部分之一,它负责在程序执行过程中处理许多关键操作,如方法调用、类信息的管理、消息转发等。深入...
### Objective-C 2.0:全面解析与学习指南 #### 一、Objective-C 2.0简介 Objective-C 2.0 是一种通用的、面向对象的编程语言,由苹果公司在2007年WWDC(全球开发者大会)上发布。它作为Cocoa框架的核心语言,在...
### Objective-C 2.0 编程(第四版) 关键知识点详解 #### 一、Objective-C概述 Objective-C是一种面向对象的编程语言,它在C语言的基础上添加了面向对象的功能,是苹果公司用于开发iOS和macOS应用程序的主要语言之一...