美文网首页ios程序员
id 、NSObject * 和 id<NSObject&

id 、NSObject * 和 id<NSObject&

作者: 王小明if | 来源:发表于2014-01-14 01:40 被阅读913次

    今天 allen 问了我一个问题,idNSObject之间有什么区别,经过大神henry指点给我这个网址 id vs NSObject* vs id<NSObject>,大致明白其中的原理。


    id foo1;
    NSObject *foo2;
    id<NSObject> *foo3;
    
    • id
      在实际编码中,我们经常看到第一个,在编译器眼中,id 仅仅意味着一个指向对象的指针,关于这个对象的信息,编译器需要等到runtime才能确定。因此,在程序中,不管对由id指向的对象发送任何消息,编译器都不会有任何报错,就像我们常见的 id obj = [[Foo alloc] init] 一样,由于 Foo alloc 返回的是 id 对象,因此对其调用init 方法与对其调用 initWithbalbalbal 等方法都是可以的(当然,现在的编译器会只能地警告,之前没见过这个 selector )。
    • NSObject
      id 指向的对象并不全是 NSObject 的子类,当我们指定一个类为 NSObject 时,编译器就确切地知道了该类的所有信息,因此,当我们对该对象发送 NSObject 没有声明的方法时,编译器就会果断报错 = =
      在别的语言中,声明一个类似 NSObject 的对象并进行操作是非常普遍的,因为 NSObject 意味着所有类的基类,但在objc这门动态语言中,过于严格的类型检查是不受欢迎的,在框架中,并不是所有类都继承自 NSObject,比如说 NSProxy,尽管它声明了大多数与 NSObject 同样的方法,但它的基类并不是NSObject,这时候,id<NSObject> 就发挥出作用了。
    • id<NSObject>
      将一个对象声明为 id<NSObject> ,意味着编译器不对其作任何类型检查,但是这个对象所属的类默认实现名为 NSObject 的protrol(是的,也有一个协议叫 NSObject )。其实,在实际操作中,我们往往不会去关心一个对象的所属的类,而是这个对象会响应什么方法,id<NSObject> 表明了foo3这个指针指向了一个实现了 NSObject 协议的方法的类的对象

    因此我们应该在这三种方法中做出怎么样的选择呢,如果你是需要一个不需要任何类型检查的对象指针时,就使用 id 吧,它经常用于接收一些不确定返回值类型的函数返回值,也经常用于 delegate 上,因为在runtime时,delegate 所属的类并不重要,而是会通过 responseToSelector: 做对其相应的方法做检查。(当然也可能是通过协议指定)。

    而当你需要一个严格类型检查的对象指针时,相信我,使用 id<NSObject> 吧~因为在现有框架中,我们会大量使用 NSProxy ,这个不属于 NSObject 子类的东东,并且,我们只需要确认一个对象能用响应一系列 NSObject 的方法,我们根本不关系它所属的类。

    相关文章

      网友评论

        本文标题:id 、NSObject * 和 id<NSObject&

        本文链接:https://www.haomeiwen.com/subject/pwuctttx.html