我们常常会混淆下面三种申明(我是没有留意过):

    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&lt;NSObject&gt;差别的更多相关文章

  1. instancetype、id、NSObject的联系和区别

    1.id和instancetype都能省去具体类型,提高代码的通用性.而NSObject *则没有这种功能. 2.instancetype只能用于方法的返回类型,而id用处和NSObject *类似. ...

  2. iOS开发中id、NSObject *、id、instancetype四者有什么区别?

      在使用Objective-C语言进行iOS应用开发的时候,常常会涉及到id.NSObject *.id.instancetype这四个概念的使用,但这四者也是iOS初学者最易混淆的内容,下面小编看 ...

  3. id ,NSObject, id<NSObject>区别

    转自:http://blog.csdn.net/happytengfei/article/details/11473931 我们经常会混淆以下三种申明(我是没有留意过):    1. id foo1; ...

  4. id、NSObject *、id<NSObject>、instancetype

    1. id 与 NSObject * (1) id 是 Objective-C 对象,但是并不一定是NSObject对象,并非所有的Foundation/Cocoa对象都是继承于NSObject对象的 ...

  5. NSObject class和NSObject protocol的关系(抽象基类与协议)

    [转载请注明出处] 1.接口的实现 对于接口这一概念的支持,不同语言的实现形式不同.Java中,由于不支持多重继承,因此提供了一个Interface关键词.而在C++中,通常是通过定义抽象基类的方式来 ...

  6. id和NSObject *和instanceType的区别与联系

    id 被成为万能指针,也就是可以指向任何对象. NSObject * 本身就是定义指向NSObject类型的指针. 那么这两者有什么区别吗? 这两者都是既可以作为返回值,又可以作为变量修饰.而其主要区 ...

  7. ExtJs4学习(四):Extjs 中id与itemId的差别

       为了方便表示或是指定一个组件的名称,我们一般会使用id或者itemId进行标识命名. (推荐尽量使用itemId.这样能够降低页面唯一标识而产生的冲突) id:   id是作为整个页面的Comp ...

  8. NSObject头文件解析 / 消息机制 / Runtime解读 (一)

    NSObject头文件解析 当我们需要自定义类都会创建一个NSObject子类, 比如: #import <Foundation/Foundation.h> @interface Clas ...

  9. YYModel 源码解读(二)之NSObject+YYModel.h (4)

    接下来我们继续向下看 typedef struct { void *modelMeta; ///< _YYModelMeta void *model; ///< id (self) voi ...

随机推荐

  1. J - 搞笑版费马大定理

    J - 搞笑版费马大定理 Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit  ...

  2. 在zendstudio上配置SVN

    本文介绍zendstudio结合SVN的使用方法. 一.部署svn服务器 直接安装用svn软件,配置太过麻烦,用户和版本库.权限管理不太方便.推荐使用CollabNetSubversionEdge.以 ...

  3. perl正则表达式第三周笔记

    正则引擎的分类 正则引擎的分类 正则引擎的分类主要分两种: DFA:egrep.awk.lex.flex NFA:.NET.PHP.Perl.Ruby.Python.GNU Emacs.ed.sec. ...

  4. R与数据分析旧笔记(六)多元线性分析 上

    > x=iris[which(iris$Species=="setosa"),1:4] > plot(x) 首先是简单的肉眼观察数据之间相关性 多元回归相较于一元回归的 ...

  5. hdu 1823 Luck and Love 二维线段树

    题目链接 很裸的题, 唯一需要注意的就是询问时给出的区间并不是l<r, 需要判断然后交换一下, WA了好多发... #include<bits/stdc++.h> using nam ...

  6. mysql-connector-c 安装

    cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/usr/local make make install

  7. 把WinXP装进内存 性能飚升秒杀固态硬盘

    现在用户新配置的电脑,内存很少有小于2GB的,配置4GB内存的朋友也有不少.容量如此大的内存,我们在使用电脑的日常操作中绝对用不完.而目前制约系统性能最大的瓶颈就是硬盘的传输速度,所以,这里教你怎么把 ...

  8. Java泛型的一点用法(转)

    1.一个优秀的泛型,建议不要这样写public static <K, V> Map<K, V> getMap(String source, String firstSplit, ...

  9. 如何解决dns解析故障

    在实际应用过程中可能会遇到DNS解析错误的问题,就是说当我们访问一个域名时无法完成将其解析到IP地址的工作,而直接输入网站IP却可以正常访问,这就是因为DNS解析出现故障造成的.这个现象发生的机率比较 ...

  10. EGit with eclipse to clone project from GitHub(Step by step)

    转载请注明出处! 1. To find your project URL inside GitHub: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWF ...