IOS_OC_id ,NSObject, id<NSObject>差别
我们常常会混淆下面三种申明(我是没有留意过):
1. id foo1;
2. NSObject *foo2;
3. id<NSObject> foo3;
第一种是最经常使用的,它简单地申明了指向对象的指针,没有给编译器不论什么类型信息,因此,编译器不会做类型检查。但也由于是这样,你能够发送不论什么信息给id类型的对象。这就是为什么+alloc返回id类型,但调用[[Foo alloc] init]不会产生编译错误。
因此,id类型是执行时的动态类型,编译器无法知道它的真实类型,即使你发送一个id类型没有的方法,也不会产生编译警告。
我们知道,id类型是一个Objective-C对象,但并非都指向继承自NSOjbect的对象,即使这个类型和NSObject对象有非常多共同的方法,像retain和release。要让编译器知道这个类继承自NSObject,一种解决的方法就是像第2种那样,使用NSObject静态类型,当你发送NSObject没有的方法,像length或者count时,编译器就会给出警告。这也意味着,你能够安全地使用像retain,release,description这些方法。
因此,申明一个通用的NSObject对象指针和你在其他语言里做的类似,像java,但其他语言有一定的限制,没有像Objective-C这样灵活。并非全部的Foundation/Cocoa对象都继承息NSObject,比方NSProxy就不从NSObject继承,所以你无法使用NSObject*指向这个对象,即使NSProxy对象有release和retain这种通用方法。为了解决问题,这时候,你就须要一个指向拥有NSObject方法对象的指针,这就是第3种申明的使用情景。
id告诉编译器,你不关心对象是什么类型,但它必须遵守NSObject协议(protocol),编译器就能保证全部赋值给id类型的对象都遵守NSObject协议(protocol)。这种指针能够指向不论什么NSObject对象,由于NSObject对象遵守NSObject协议(protocol),并且,它也能够用来保存NSProxy对象,由于它也遵守NSObject协议(protocol)。这是很强大,方便且灵活,你不用关心对象是什么类型,而仅仅关心它实现了哪些方法。
如今你知道你要用什么类型了不?
假设你不须要不论什么的类型检查,使用id,它常常作为返回类型,也常常常使用于申明代理(delegate)类型。由于代理类型通常在执行时,才会检查是否实现了那些方法。
假设真的须要编译器检查,那你就考虑使用第2种或者第3种。非常少看到NSObject*能正常执行,但id无法正常执行的。使用协议(protocol)的长处是,它能指向NSProxy对象,而更经常使用的情况是,你仅仅想知道某个对象遵守了哪个协议,而不用关心它是什么类型。
IOS_OC_id ,NSObject, id<NSObject>差别的更多相关文章
- instancetype、id、NSObject的联系和区别
1.id和instancetype都能省去具体类型,提高代码的通用性.而NSObject *则没有这种功能. 2.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. ...
- iOS开发中id、NSObject *、id、instancetype四者有什么区别?
在使用Objective-C语言进行iOS应用开发的时候,常常会涉及到id.NSObject *.id.instancetype这四个概念的使用,但这四者也是iOS初学者最易混淆的内容,下面小编看 ...
- id ,NSObject, id<NSObject>区别
转自:http://blog.csdn.net/happytengfei/article/details/11473931 我们经常会混淆以下三种申明(我是没有留意过): 1. id foo1; ...
- id、NSObject *、id<NSObject>、instancetype
1. id 与 NSObject * (1) id 是 Objective-C 对象,但是并不一定是NSObject对象,并非所有的Foundation/Cocoa对象都是继承于NSObject对象的 ...
- NSObject class和NSObject protocol的关系(抽象基类与协议)
[转载请注明出处] 1.接口的实现 对于接口这一概念的支持,不同语言的实现形式不同.Java中,由于不支持多重继承,因此提供了一个Interface关键词.而在C++中,通常是通过定义抽象基类的方式来 ...
- id和NSObject *和instanceType的区别与联系
id 被成为万能指针,也就是可以指向任何对象. NSObject * 本身就是定义指向NSObject类型的指针. 那么这两者有什么区别吗? 这两者都是既可以作为返回值,又可以作为变量修饰.而其主要区 ...
- ExtJs4学习(四):Extjs 中id与itemId的差别
为了方便表示或是指定一个组件的名称,我们一般会使用id或者itemId进行标识命名. (推荐尽量使用itemId.这样能够降低页面唯一标识而产生的冲突) id: id是作为整个页面的Comp ...
- NSObject头文件解析 / 消息机制 / Runtime解读 (一)
NSObject头文件解析 当我们需要自定义类都会创建一个NSObject子类, 比如: #import <Foundation/Foundation.h> @interface Clas ...
- YYModel 源码解读(二)之NSObject+YYModel.h (4)
接下来我们继续向下看 typedef struct { void *modelMeta; ///< _YYModelMeta void *model; ///< id (self) voi ...
随机推荐
- Svn服务启动的两种方式
一.svn服务器启动 cmd命令行启动:vsvnserve -d –r 文档仓库路径 -d 后台执行 -r 版本库的根目录 二.Windows服务自动启动 利用xp.2000 以上的 ...
- Hibernate学习之关系映射(转)
一.一对多 "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系.一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多.多对一:从订单的角度来说多个订单可以对应一 ...
- hdu 1524 A Chess Game 博弈
题目链接 给出一个有向无环图, 上面放有一些棋子, 两个人轮流移动棋子, 当一个人无法移动时, 算输. 求出每一个点的sg值, 异或就可以.出度为0的点sg值为0. #include<bits/ ...
- vcredist作用
一.vcredist作用: vcredist_x86.exe是微软公司Visual C++的32位运行时库,包含了一些Visual C++的库函数. vcredist_x64.exe是微软公司Visu ...
- javascript 修改css样式
abc.css CSS code .class1 { width:10px; background-color: red; } HTML code <!DOCTYPE ...
- Apache配置支持include
Apache配置支持include 什么是SSI? SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思.从技术角度上说,SSI就是HTML文件中,可以通过注释 ...
- elk 数据存储
让我们在集群中唯一一个空节点上创建一个叫做blogs的索引,默认情况下,一个索引被分配5个主分片, 但是为了演示的目的, 我们只分配3个主分片和一个复制分片(每个主分片都有一个复制分片): PUT / ...
- /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found,解压rpm包
如果是64位系统报错信息如下: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by 原因是没有GLIB ...
- 多名Uber司机被指刷单遭封号 一周薪水为0
昨天,一司机在Uber“司机之家”办公地墙上写了泄愤的话 摄/法制晚报记者 苏妮 司机展示的账单显示,上周的薪水几乎为零,上面用英文标注了“欺诈行为”的字样 摄/法制晚报记者 苏妮 法制晚报讯(记者 ...
- hdoj Scaena Felix
Scaena Felix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...