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 ...
随机推荐
- Linux进程之Fork函数
Fork()函数 1.所需头文件: #include <unistd.h> #include<sys/types.h> 2.函数定义 pid_t fork( void ); p ...
- Mac 安装Django
首先 我电脑上的python 是 安装Django 是需要通过 pip 来安装的 最新办的python3.4 应该内置了pip 因此这里 需要下载安装pip pip是常用的Python包管理 ...
- mysql查询今天、昨天、近7天、近30天、本月、上一月的SQL语句
mysql查询今天.昨天.近7天.近30天.本月.上一月的SQL语句 这篇文章主要介绍了mysql查询今天.昨天.近7天.近30天.本月.上一月的SQL语句,一般在一些统计报表中比较常用这个时间段,需 ...
- SpringBoot里的一些注解
Spring不仅可以通过xml配置获取*.properties,还可以通过@Value注解的方式来获取,将properties配置文件中的属性值注入到java成员变量. 如果不想每次都写private ...
- 整理Javascript基础数据和引用数据复制值的问题
Javascript数据分为两大类:1.基础类型(原始类型数据) 2.引用类型.他们的存储方式是不同的 基础类型的数据存储是保存在栈内存中的: 例如: var a=1; var b=a; var a= ...
- Codeforces 766C Mahmoud and a Message 2017-02-21 13:57 62人阅读 评论(0) 收藏
C. Mahmoud and a Message time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- Java异常封装
转载: Java异常封装 Java里面的异常在真正工作中使用还是十分普遍的.什么时候该抛出什么异常,这个是必须知道的. 当然真正工作里面主动抛出的异常都是经过分装过的,自己可以定义错误码和异常描述. ...
- 18-11-03 Scrum Meeting 6
1. 会议照片 2. 工作记录 完成的工作 配置页面 实现中译英选择题和英译中选择题的查询接口 整理文档 完成一个网站的图片爬取 计划的工作 完善配置页面功能 补充另一个网站的图片爬取 代码整理测试 ...
- 饿了么 PostgreSQL 优化之旅
1. 架构演变 在O2O外卖领域,基于位置服务的需求越来越多,这就要求DB能够存储地理位置信息,而在开源数据库中,对空间地理数据支持比较好的要数PG的插件Postgis. 饿了么在使用PG的过程中,由 ...
- 解决vs2017调试出现脚本错误(/Community/Common7/IDE/PrivateAssemblies/plugin.vs.js) 方法
原文地址:http://bkcoding.cn/post_1204.html 新装的vs2017编译时出现当前页面脚本错误 url:/Community/Common7/IDE/PrivateAsse ...