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框架。
这两个框架在系统中处于的位置如图:
![](https://i-blog.csdnimg.cn/blog_migrate/d243fbaa5734b2da0e2d2341011c9489.webp?x-image-process=image/format,png)
1.2、Foundation框架 好吧,那我们看看两个框架的类组织架构图,第一个先看Foundation的,三个图,包括了Foundation所以的类,图中灰色的是iOS不支持的,灰色部分是OS X系统的。
![](https://i-blog.csdnimg.cn/blog_migrate/96ca4ef353bad7145fed043313267e2c.webp?x-image-process=image/format,png)
![](https://i-blog.csdnimg.cn/blog_migrate/fc4a5121ea9f9eb41d4298049319a864.webp?x-image-process=image/format,png)
![](https://i-blog.csdnimg.cn/blog_migrate/4493362d4978c082302ddd76078c230b.webp?x-image-process=image/format,png)
将上图Foundation框架中的类进行逻辑分类如下:
- 值对象
- 集合
- 操作系统服务,包括下面三个:
文件系统和URL进程间通讯。 这个范畴中的大部分类代表不同的系统端口、套接字、和名字服务器,对实现底层的IPC很有用。NSPipe代表一个BSD管道,即一种进程间的单向通讯通道。 线程和子任务。 NSThread类使您可以创建多线程的程序,而各种锁(lock)类则为彼此竞争的线程在访问进程资源时提供各种控制机制。通过NSTask,您的程序可以分出 一个子进程来执行其它工作或进行进度监控。
- 通知
- 归档和序列化
- 表达式和条件判断
- Objective-C语言服务
- 在用户界面工具(interface Buidler)从对象库里 拖拽窗口,视图或者其他的对象使用。
- 用代码创建
- 通过继承UIView类或间接继承UIView类实现自定义用户界面
![](https://i-blog.csdnimg.cn/blog_migrate/f5822a31d9e00d1e8bfe8e7bef253854.webp?x-image-process=image/format,png)
在图中可以看出,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的优点是它是动态的。动态能力有三种:
- 动态类-运行时确定类的对象
- 动态绑定-运行时确定要调用的方法
- 动态加载--运行时为程序加载新的模块
那我们看看isa指针类型的数据结构是什么样的?如果抛开NSObject对象的其他的成员数据和变量,NSObject可以看成这样:
[Objective-C]
纯文本查看
复制代码
1
2
3
|
@interface
NSObject
<
NSObject
> {
Class isa;
}
|
不考虑@interface关键字在编译时的作用,可以把NSObject更接近C语言结构表示为:
[Objective-C]
纯文本查看
复制代码
1
2
3
|
struct
NSObject
{
Class isa;
}
|
Class是用typedef定义的
[Objective-C]
纯文本查看
复制代码
1
|
typedef
struct
objc_class *Class;
|
那NSObject可以这么写了
[Objective-C]
纯文本查看
复制代码
1
2
3
|
struct
NSObject
{
objc_class *isa
}
|
其中objc_class的结构是什么样的呢?大概是这样的:
[Objective-C]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
struct
objc_class {
Class isa;
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;
struct
objc_protocol_list *protocols;
}
|
这里会看到,在这个结构体里还有一个isa指针,又是一 重指向 ,是不是有种到了盗梦空间的感觉。不用紧张,take easy,不会有那么多层次的,这里的isa指针指向的是 元类对象 (metaclass object),带有元字,证明快到头了。那 元类对象 有啥用呢?它用来存储的关于类的版本,名字,类方法等信息。所有的 元类对象 (metaclass object)都指向 NSObject的元类对象 ,到头还是 NSObject 。一共三次:类对象->元类对象->NSObject元类对象。
为了得到整个类组织架构的信息,objc_class结构里定义了第二个成员变量Class super_class,它指向父类的类对象。说了这么多,可能关系缕不清楚,有道是一张图胜过千言万语:
![](https://i-blog.csdnimg.cn/blog_migrate/40170b2dd8cdc3eb837f1e5b308fc96d.webp?x-image-process=image/format,png)
图中可以看出,D3继承D2,D2继承D1,D1最终继承NSObject。下图从D3的一个对象开始,排列出D3 D2 D1 NSObject 类对象,元类对象等关系。
![](https://i-blog.csdnimg.cn/blog_migrate/92c6d8082c22f8869212d99e3b57cccc.webp?x-image-process=image/format,png)
图中的箭头都是 指针 的指向。
2.4 根类 NSObject NSObject是大部分Objective-C类的根类,它没有父类。其它类继承NSObject,访问Objective-C运行时系统的基本接口,这样其他类的实例可以获得运行时的能力。
![](https://i-blog.csdnimg.cn/blog_migrate/280709ca9103ddeea3d82de37c1e580e.webp?x-image-process=image/format,png)
2.4.1 根类和根类协议 NSObject不但是个 类 名,NSObject也是个 协议 的名称,参考NSObject协议 , NSObject协议指定了根类必须实现的接口。
2.4.2 根类的主要方法:
- 分配、初始化、和复制:
- alloc和allocWithZone:方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。
- init方法是对象初始化。
- new是一个将简单的内存分配和初始化结合起来的方法。
- copy和copyWithZone。
- 对象的保持和清理:
- retain方法增加对象的保持次数。
- release方法减少对象的保持次数。
- autorelease方法也是减少对象的保持次数,但是以推迟的方式。
- retainCount方法返回对当前的保持次数。
- dealloc方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。
- 内省和比较
- superclass和class方法(实现为类和实例方法)分别以Class对象的形式返回接收者的父类和类。
- 您可以通过isKindOfClass:和isMemberOfClass:方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。
- isSubclassOfClass:类方法则用于测试类的继承性。
- respondsToSelector:方法用于测试接收者是否实现由选择器参数标识的方法。
- instancesRespondToSelector:类方法则用于测试给定类的实例是否实现指定的方法。
- conformsToProtocol:方法用于测试接收者(对象或类)是否遵循给定的协议。
- isEqual:和hash方法用于对象的比较。
- description方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示对象。
- 对象的编码和解码
encodeWithCoder:和initWithCoder:是NSCoding协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。NSObject类中声明了一些于对象编码有关的方法:
classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。
- 消息的转发
- 消息的派发
2.5 Cocoa对象生命周期 对象的四种内存管理方式,如下图所示
- 对象的生命周期—简化视图
![](https://i-blog.csdnimg.cn/blog_migrate/2af2a7d851d057a49b82960313177bcb.webp?x-image-process=image/format,png)
- 保持接收到的对象
![](https://i-blog.csdnimg.cn/blog_migrate/3aba9126592b833d4a9dabf1eb5f0009.webp?x-image-process=image/format,png)
- 拷贝接收到的对象
![](https://i-blog.csdnimg.cn/blog_migrate/0f40bb9d7ca088643b301b1dfed1ab11.webp?x-image-process=image/format,png)
- 自动释放池
![](https://i-blog.csdnimg.cn/blog_migrate/75c095544b1e4db18e6567d4635c78b6.webp?x-image-process=image/format,png)