Cocoa对象——根类
[转载自:http://mobile.51cto.com/iphone-274229.htm]
Cocoa对象 根类是本文要介绍的内容,仅凭Objective-C语言和运行环境并不足以构造哪怕是最简单的面向对象的程序,至少是不容易的。还缺少一些东西:即所有对象公有的基本行为和接口的定义。根类正是提供了这些定义。
之所以叫根类,是因为它位于整个类层次(这里是指Cocoa的类层次)的根上。根类不从其它类继承,但是类层次中的所有其它类都最终从根类继承下来。根类连同Objective-C语言,是Cocoa直接访问Objective-C运行环境或与之交互的基本途径。Cocoa对象的大部分对象行为能力都是从根类得到的。
Cocoa提供了两个根类:NSObject和NSProxy。Cocoa将后者定义为抽象类,用于表示其它对象的替身对象。因此NSProxy类在分布式对象架构中是很重要的。由于作用比较特别,NSProxy在Cocoa程序中出现频率很低。Cocoa开发者在提到根类时,几乎总是指NSObject。
本部分将讨论NSObject类,看看它如何与运行环境进行交互,以及它为所有Cocoa对象定义的基本行为和接口。其中主要是它为对象的内存分配、初始化、内存管理、内省、以及运行环境支持所声明的方法。这些概念是理解Cocoa的基础。
NSObject
NSObject是大多数Objective-C类层次的根类,它没有超类。其它类从NSObject继承访问Objective-C语言运行时系统的基本接口,它们的实例可以得到对象行为的能力。
虽然NSObject不是一个严格的抽象类,但它是个虚类。仅凭一个NSObject实例除了作为一个简单的对象外,不能完成任何有用的工作。为了在您的程序中加入特有的属性和逻辑,必须创建一个或多个从NSObject或其派生类继承下来的类。
NSObject采纳了NSObject协议(参见"根类—和协议"部分)。NSObject协议支持多个根对象。举例来说,NSProxy是另一个根类,它不是继承自NSObject,但采纳了NSObject协议,以便和其它Objective-C对象共用一个公共的接口。
NSObject和java.lang.Object一起,是Java版本的Cocoa中所有类的根类,包括Foundation和Application Kit。
根类—和协议
NSObject不仅仅是一个类的名称,还是一个协议的名称。两者对于定义一个Cocoa对象都是必要的。NSObject协议指定了Cocoa中所有根类必须的基本编程接口,因此不仅NSObject类采纳了这个同名的协议,其它根类也采纳这个协议,比如NSProxy。NSObject类进一步指定了不作为代理对象的Cocoa对象的基本编程接口。
NSObject及类似的协议用于Cocoa对象的总体定义(而不是在类接口中包含那些协议),使多个根类成为可能。每个根类共用一个由它们采纳的协议定义的公共接口。
在另一种意义上,NSObject不仅仅是个“根”协议。虽然NSObject类没有正式采纳NSCopying、NSMutableCopying、和NSCoding协议,但它声明和实现了与那些协议相关的方法(而且,包含NSObject类的NSObject.h头文件中也包含上面提到的所有四个协议的定义)。对象拷贝、编码、和解码是对象行为的基本部分。很多子类(如果不是绝大多数的话)都希望采纳和遵循这些协议。
请注意:其它Cocoa类可以(而且确实是)通过范畴将方法添加到NSObject中。这些范畴通常是一些非正式的协议,在委托中使用。它们允许委托对象选择实现范畴中的部分方法。然而,NSObject的范畴并不被认为是基本对象接口的一部分。
根类方法概述
NSObject根类和它采纳的NSObject协议及其它“根” 协议一起,为所有不作为代理对象的Cocoa对象指定了如下的接口和行为特征:分配、初始化、和复制。NSObject类中的一些方法(包括一些来自协议的方法)用于对象的创建、初始化、和复制:
alloc和allocWithZone:方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。
init方法是对象初始化原型,负责将对象的实例变量设置为一个已知的初始状态。initialize和load是两个类方法,它们让对象有机会对自身进行初始化。
new是一个将简单的内存分配和初始化结合起来的便利方法。
copy和copyWithZone:方法用于拷贝实现这些(由NSCopying协议定义的)方法的类的实例。希望支持可变对象拷贝的类则需要实现mutableCopy和mutableCopyWithZone:(由NSMutableCopying协议定义)方法。
更多信息请参见 "对象的创建"部分。
对象的保持和清理。下面的方法对面向对象程序的内存管理特别重要:
retain方法增加对象的保持次数。
release方法减少对象的保持次数。
autorelease方法也是减少对象的保持次数,但是以推迟的方式。
retainCount方法返回对当前的保持次数。
dealloc方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。
更多信息请参见 Cocoa对象的生命周期
内省和比较。NSObjec有很多方法可以查询对象的运行时信息。这些内省方法有助于找出对象在类层次中的位置,确定对象是否实现特定的方法,以及测试对象是否遵循某种协议。这些方法中的一部分仅实现为类方法。
superclass和class方法(实现为类和实例方法)分别以Class对象的形式返回接收者的超类和类。
您可以通过isKindOfClass:和isMemberOfClass:方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。isSubclassOfClass:类方法则用于测试类的继承性。
respondsToSelector:方法用于测试接收者是否实现由选择器参数标识的方法。instancesRespondToSelector:类方法则用于测试给定类的实例是否实现指定的方法。
conformsToProtocol:方法用于测试接收者(对象或类)是否遵循给定的协议。
isEqual:和hash方法用于对象的比较。
description方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示对象。
更多信息请参见 内省 。
对象的编码和解码。下面的方法和对象的编解码(作为归档过程的一部分)有关:
encodeWithCoder:和initWithCoder:是NSCoding协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。
NSObject类中声明了一些于对象编码有关的方法:classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。
进一步信息请参见Cocoa的归档和序列化编程指南一文。
消息的转发。forwardInvocation:和相关的方法允许一个对象将消息转发给另一个对象。
消息的派发。以performSelector...开头的一组方法使您可以在指定的延迟后派发消息,以及将消息从辅助线程派发(同步或异步)到主线程。
NSObject还有几个其它的方法,包括一些处理版本和姿态(后者使一个类在运行时将自己表示为另一个类)的类方法,以及一些访问运行时数据结构的方法,比如方法选择器和指向方法实现的函数指针。
接口规范
某些NSObject方法只是为了被调用,而另一些方法则是为了被重载。举例来说,大多数子类不应该重载allocWithZone:方法,但必须实现init方法—至少需要实现一个最终调用根类的init方法(请参见"对象的创建"部分)的初始化方法。对于那些期望子类重载的方法,NSObject的实现或者什么也不做,或者返回一个合理的值,比如self。这些缺省实现使我们有可能向任意的Cocoa对象—甚至是没有重载这些方法的对象—发送诸如init这样得基本消息,而又不必冒运行时例外的风险。在发送消息之前,不必进行检查(通过respondsToSelector:方法)。更加重要的是,NSObject的这些“占位”方法为Cocoa对象定义了一个公共的结构,并建立了一些规则,如果所有的对象都遵循这些规则,对象间的交互将更加可靠。
实例方法和类方法
运行环境系统以一种特殊的方式处理根类定义的方法。根类定义的实例方法可以由实例对象和类对象执行,因此所有类对象都可以访问根类定义的实例方法。对于任何类对象,如果对象中不包含同名的类方法,就可以执行根类的所有实例方法。
举例来说,一个类对象可以通过发送消息来执行NSObject的respondsToSelector:和performSelector:withObject:实例方法:
- SEL method = @selector(riskAll:);
- if ([MyClass respondsToSelector:method])
- [MyClass performSelector:method withObject:self];
请注意,只有根类中定义的实例方法才可以在类对象中使用。在上面的例子中,如果MyClass重新实现了respondsToSelector:或者performSelector:withObject:方法,则那些新的版本将只能用于实例对象。MyClass的类对象只能执行NSObject类定义的版本(当然,如果MyClass将respondsToSelector:或performSelector:withObject: 实现为类方法,而不是实例方法,则该类对象可以执行这些新的实现)。
Cocoa对象——根类的更多相关文章
- Python10/22--面向对象编程/类与对象/init函数
类: 语法: class关键字 类名# 类名规范 大写开头 驼峰命名法class SHOldboyStudent: # 描述该类对象的特征 school = "上海Oldboy" ...
- Java 常用对象-Object类
2017-10-31 23:42:08 Object类:类 Object 是类层次结构的根类.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个类的方法. 或者说,每个类都直接或者间 ...
- 常见对象-Object类
Object类概述 是类层次结构的根类,每个类都直接或者间接继承该类. eg: 1.class Student extends Object{} //直接继承 2.class Student ext ...
- 四、java基础-面向过程_对象_类中可出现的因素
1.面向过程和面向对象区别: 1)面向过程:开发一个应用程序.一个项目,必须先了解整个过程,了解各个步骤.模块间的因果关系,使的面向过程方式去开发程序时,代码和代码之间的关联程度是非常强.所以其中任何 ...
- .NET 基础 一步步 一幕幕[面向对象之对象和类]
对象和类 本篇正式进入面向对象的知识点简述: 何为对象,佛曰:一花一世界,一木一浮生,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清静.可见"万物皆对象". ...
- Python-面向对象(类)二
一.成员修饰符 • 共有成员 • 私有成员 __+字段 __:成员修饰符 无法直接访问,只能通过该成员所属类的方法简介访问 class Foo: def __init__(self, name, ag ...
- Python-面向对象(类)一
一.如何创建类 class cls: pass 二.创建方法 构造方法: __init__(self, arg) obj = 类('a1') 普通方法: obj = 类('xxx') obj.普通方法 ...
- CoreJava学习笔记1-基本概念、对象和类
一. java的基本程序设计结构 (一) java共有8种基本类型:4种整型,2种浮点类型,1种char,1种boolean. 1) 4种整型:byte(1).short(2). ...
- XML转换为对象操作类详解
//XML转换为对象操作类 //一,XML与Object转换类 using System.IO; using System.Runtime.Serialization.Formatters.Binar ...
随机推荐
- Spring IoC底层原理
-------------------siwuxie095 Spring IoC 底层原理 1.IoC 即 Invers ...
- sql添加/移除约束
唯一:ALTER TABLE TableName ADD CONSTRAINT UQ_NickName UNIQUE(NickName) 主键:ALTER TABLE TableName ADD CO ...
- PKUWC2019 真·游记
由于我这个大傻逼考试结果实在是没法看,所以这篇游记将尽可能略去和考试有关的内容,变成一篇真正的游记…… 接下来的内容中将会出现各种旅游攻略,寻求干货的同学可以提前左转了. Day -7 学考终于结束了 ...
- OSX 下 sftp 上传目录到服务器
使用如下命令: put –r dir mput –r dir
- 我们为什么要在 PHPStorm 中标记目录
问题来源 (1)要开发的项目位于PHPStorm打开的项目的二级目录下,使用PHPStorm来开发Laravel项目 提供的教程在代码自动定位和智能提醒方面,存在无效的情况: (2)使用gulp作为项 ...
- sqlserver怎么将excel表的数据导入到数据库中
在数据库初始阶段,我们有些数据在EXCEL中做好之后,需要将EXCEL对应列名(导入后对应数据库表的字段名),对应sheet(改名为导入数据库之后的表名)导入指定数据库, 相当于导入一张表的整个数据. ...
- POJ1789 Truck History 2017-04-13 12:02 33人阅读 评论(0) 收藏
Truck History Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27335 Accepted: 10634 D ...
- windows下C++操作MySQL数据库
.安装MySQL 2.建立C++控制台程序,新建CPP源文件,如:sqlconn.cpp 3.工程项目中属性—C/C++--常规—附加包含目录中添加mysql安装目录中的MySQL\MySQL\MyS ...
- 第一周leetcode
3/27 胡乱投了一堆简历,做了七牛的笔试,看了腾讯的面试题 感觉不懂的还是很多啊,不过也知道了笔试套路其实也不多,基本算法/数据结构(不会太难).c/c++基础(后面的知识类似虚函数需要了解).li ...
- 2、Docker和虚拟机的对比
2.1 虚拟化技术 虚拟机Virtual Machine与容器化技术(代表Docker)都是虚拟化技术,两者的区别在于虚拟化的程度不同. Docker为代表的容器化技术并不是虚拟机. 虚拟 ...