Cocoa框架是iOS应用程序的基础,了解Cocoa框架,对开发iOS应用有很大的帮助。

1、Cocoa是什么?

Cocoa是OS X和 iOS操作系统的程序的运行环境。

是什么因素使一个程序成为Cocoa程序呢?不是编程语言,因为在Cocoa开发中你可以使用各种语言;也不是开发工具,你可以在命令行上就可以创建Cocoa程序。Cocoa程序可以这么说,它是由一些对象组成,而这些对象的类最后都是继承于它们的根类 :NSObject。而且它们都是基于Objective-C运行环境的。

1.1、Cocoa框架

iOS中,Cocoa众多框架中最重要最基本的两个框架是:Foundation 和 UIKit。

Foundation 和界面无关,也可以说和界面无关的类基本是Foundation框架的,和界面相关的是UIKit框架。

这两个框架在系统中处于的位置如图:

1.2、Foundation框架

好吧,那我们看看两个框架的类组织架构图,第一个先看Foundation的,三个图,包括了Foundation所以的类,图中灰色的是iOS不支持的,灰色部分是OS X系统的。

 

将上图Foundation框架中的类进行逻辑分类如下:

  1. 值对象
  2. 集合
  3. 操作系统服务 包括下面三个:文件系统和URL   进程间通讯。 这个范畴中的大部分类代表不同的系统端口、套接字、和名字服务器,对实现底层的IPC很有用。NSPipe代表一个BSD管道,即一种进程间的单向通讯通道。   线程和子任务。 NSThread类使您可以创建多线程的程序,而各种锁(lock)类则为彼此竞争的线程在访问进程资源时提供各种控制机制。通过NSTask,您的程序可以分出      一个子进程来执行其它工作或进行进度监控。
  4. 通知
  5. 归档和序列化
  6. 表达式和条件判断
  7. Objective-C语言服务

1.3 UIKit框架

应用程序可以通过三种方式使用UIKit创建界面
  1. 在用户界面工具(interface Buidler)从对象库里 拖拽窗口,视图或者其他的对象使用。
  2. 用代码创建
  3. 通过继承UIView类或间接继承UIView类实现自定义用户界面
 
框架类组织架构图:
 
 

在图中可以看出,responder 类是图中最大分支的根类,UIResponder为处理响应事件和响应链 定义了界面和默认行为。当用户用手指滚动列表或者在虚拟键盘上输入时,UIKit就生成时间传送给UIResponder响应链,直到链中有对象处理这个事件。相应的核心对象,比如:UIApplication  ,UIWindow,UIView都直接或间接的从UIResponder继承。

2、Cocoa对象

2.1 Objective-C是面向对象的语言

Objective-C和Java C++一样,有封装,继承,多态,重用。但是它不像C++那样有重载操作法、模版和多继承,也没有Java的垃圾回收机制。

2.2 Objective-C的优点

Objective-C语言有C++ Java等面向对象的特点,那是远远不能体现它的优点的。Objective-C的优点是它是动态的。动态能力有三种:

动态类-运行时确定类的对象

动态绑定-运行时确定要调用的方法

动态加载--运行时为程序加载新的模块

2.3 动态能力相关的isa指针

每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针。这个指针指向哪呢?它指向一个类对象(class object  记住它是个对象,是占用内存空间的一个变量,这个对象在编译的时候编译器就生成了,专门来描述某个类的定义),这个类对象包含了Objective-C对象的一些信息(为了区分两个对象,我把前面提到的对象叫Objective-C对象),包括Objective-C对象的方法调度表,实现了什么协议等等。这个包含信息就是Objective-C动态能力的根源了。

那我们看看isa指针类型的数据结构是什么样的?如果抛开NSObject对象的其他的成员数据和变量,NSObject可以看成这样:

  1. @interface NSObject <NSObject> {
  2. Class    isa;
  3. }

不考虑@interface关键字在编译时的作用,可以把NSObject更接近C语言结构表示为:

  1. struct NSObject{
  2.   Class isa;
  3. }

Class是用typedef 定义的

  1. typedef struct objc_class *Class;

那NSObject可以这么写了

  1. struct NSObject{
  2.   objc_class *isa
  3. }

那objc_class的结构是什么样的呢?大概是这样的:

  1. struct objc_class {
  2. Class isa;
  3. Class super_class;
  4. const char *name;
  5. long version;
  6. long info;
  7. long instance_size;
  8. struct objc_ivar_list *ivars;
  9. struct objc_method_list **methodLists;
  10. struct objc_cache *cache;
  11. struct objc_protocol_list *protocols;
  12. }

这里会看到,在这个结构体里还有一个isa指针,又是一重指向,是不是有种到了盗梦空间的感觉。不用紧张,take easy,不会有那么多层次的,这里的isa指针指向的是元类对象(metaclass object),带有元字,证明快到头了。那元对象有啥用呢?它用来存储的关于类的版本,名字,类方法等信息。所有的元类对象(metaclass object)都指向 NSObject的元类对象,到头还是NSObject。一共三次:类对象->元类对象->NSObject元类对象。

为了得到整个类组织架构的信息,objc_class结构里定义了第二个成员变量Class super_class,它指向父类的类对象。说了这么多,可能关系缕不清楚,有道是一张图胜过千言万语

图中可以看出,D3继承D2,D2继承D1,D1最终继承NSObject。下图从D3的一个对象开始,排列出D3 D2 D1 NSObject 类对象,元类对象等关系。

图中的箭头都是指针的指向。

2.4 根类 NSObject

NSObject是大部分Objective-C类的根类,它没有父类。其它类继承NSObject,访问Objective-C运行时系统的基本接口,这样其他类的实例可以获得运行时的能力。

2.4.1 根类和根类协议

NSObject不但是个类名,NSObject也是个协议的名称,参考NSObject协议 , NSObject协议指定了根类必须实现的接口。

2.4.2 根类的主要方法:

  • 分配、初始化、和复制:

alloc和allocWithZone:方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。
init方法是对象初始化。
new是一个将简单的内存分配和初始化结合起来的方法。
copy和copyWithZone:

  • 对象的保持和清理:

retain方法增加对象的保持次数。
release方法减少对象的保持次数。
autorelease方法也是减少对象的保持次数,但是以推迟的方式。
retainCount方法返回对当前的保持次数。
dealloc方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。

  • 内省和比较

NSObjec有很多方法可以查询对象的运行时信息。这些内省方法有助于找出对象在类层次中的位置,确定对象是否实现特定的方法,以及测试对象是否遵循某种协议。下面是部分方法 
superclass和class方法(实现为类和实例方法)分别以Class对象的形式返回接收者的父类和类。
您可以通过isKindOfClass:和isMemberOfClass:方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。isSubclassOfClass:类方法则用于测试类的继承性。
respondsToSelector:方法用于测试接收者是否实现由选择器参数标识的方法。instancesRespondToSelector:类方法则用于测试给定类的实例是否实现指定的方法。
conformsToProtocol:方法用于测试接收者(对象或类)是否遵循给定的协议。
isEqual:和hash方法用于对象的比较。
description方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示对象。

  • 对象的编码和解码

下面的方法和对象的编解码(作为归档过程的一部分)有关:
encodeWithCoder:和initWithCoder:是NSCoding协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。
NSObject类中声明了一些于对象编码有关的方法:classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。

  • 消息的转发

 forwardInvocation:允许一个对象将消息转发给另一个对象。

  • 消息的派发

在performSelector开头的一些方法允许你延迟后派发指定消息,而且可以将消息(同步或异步的消息)从辅助线程派发到主线程。

2.5 Cocoa对象生命周期

对象的四种内存管理方式,如下图所示

  •  对象的生命周期—简化视图

  • 保持接收到的对象

  • 拷贝接收到的对象

  • 自动释放池

参考:

1、http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf

2、http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html

3、http://www.cnblogs.com/csutanyu/archive/2011/12/12/Objective-C_memory_layout.html

关于oc运行时 isa指针详解的更多相关文章

  1. 自动化运维工具——ansile详解

    自动化运维工具——ansible详解(一) 目录 ansible 简介 ansible 是什么? ansible 特点 ansible 架构图 ansible 任务执行 ansible 任务执行模式 ...

  2. OC中NSLog函数输出格式详解

    OC中NSLog函数输出格式详解 %@ 对象 • %d, %i 整数 • %u 无符整形 • %f 浮点/双字 • %x, %X 二进制整数 • %o 八进制整数 • %zu size_t • %p ...

  3. 【C++】智能指针详解(一):智能指针的引入

    智能指针是C++中一种利用RAII机制(后面解释),通过对象来管理指针的一种方式. 在C++中,动态开辟的内存需要我们自己去维护,在出函数作用域或程序异常退出之前,我们必须手动释放掉它,否则的话就会引 ...

  4. c/c++指针详解(一)

    一:相关概念 1.指针数组:int *p[6]               是数组,是一个存放指针的数组,也就是里面存放的是地址. 2.数组指针:int (*p)[6]                 ...

  5. c/c++指针详解(二)

    指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占 ...

  6. Delphi指针详解

    Delphi指针详解2007-12-04 06:08:57|  分类: DLL学习 阅读91 评论0   字号:大中小 订阅 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用 ...

  7. [转]C++ 智能指针详解

    转自:http://blog.csdn.net/xt_xiaotian/article/details/5714477 C++ 智能指针详解 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每 ...

  8. C++ 智能指针详解(转)

    C++ 智能指针详解   一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常 ...

  9. C++指针详解 (转)

    C++指针详解 指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区, ...

随机推荐

  1. JavaWeb 6 Http

    6 Http 2 Http协议入门        2.1 什么是http协议                http协议: 对浏览器客户端 和  服务器端 之间数据传输的格式规范 2.2 查看http ...

  2. ios 开发之 Xcode6 No valid signing identities (i.e. certificate and private key pair) matching...

    之前的项目用证书真机测试过,我想再无证书Build,出现下面的报错提示! 下面的team我无法改成None!一点击None选的还是Unhonw name(JPGE28K3W9)这个是报错的关键 最后由 ...

  3. golang执行linux命令

    golang exec 执行系统命令 golang    2014-09-25 13:17:44    2779    0    0 exec.Command() 最简单的方法: cmd := exe ...

  4. Sqlserver_视图

    SQL CREATE VIEW 语句 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个数据库中的真实的表中的字段. 您可 ...

  5. php中高级基础知识点

    1. 基本知识点 HTTP协议中几个状态码的含义:1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码   说明 100   (继续) 请求者应当继续提出请求. 服务器返回此代码 ...

  6. Hive优化

    hive.optimize.cp=true:列裁剪hive.optimize.prunner:分区裁剪hive.limit.optimize.enable=true:优化LIMIT n语句hive.l ...

  7. aspcms标签使用经验

    1.调用导航栏标签写法,sort是网站后台栏目管理的编号{aspcms:type sort=19} <a href="[type:link]" title="[ty ...

  8. VR应用里面的Photogrammetry技术是什么

    http://www.manew.com/thread-49556-1-1.html 具体使用 http://www.didayin.com/archives/632 软件下载 http://labs ...

  9. 资源 之 4.3 访问Resource(拾壹)

    4.3.1  ResourceLoader接口 ResourceLoader接口用于返回Resource对象:其实现可以看作是一个生产Resource的工厂类. public interface Re ...

  10. hdu1157 快排

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1157 大意:排序,取中间数. PS:1.自己实现了下快排函数,也可以使用#include<algor ...