id、NSObject *、id<NSObject>、instancetype的区别

1. id 与 NSObject *

(1) id 是 Objective-C 对象,但是并不一定是NSObject对象,并非所有的Foundation/Cocoa对象都是继承于NSObject对象的,比如NSProxy。同时,id与NSObject对象之间有很多的共同方法,比如retain与release等方法。更一步来说:所有的对象本质来说都是 id 类型的。

(2) 对于id来说,你可以调用任意可见的selector,编译器和IDE不会进行类型检查,这个时候就需要你自己进行类型检查并且进行类型转换,来确保这些调用不会出错。而对于NSObject *类型,只能调用NSObject对象所声明的selector,不能调用它子类的selector,编译器会进行检查。

(3) 对于一些不想或者不能进行类型检查的地方,可以使用id。比如在集合(array, collection)类型中,比如在一些你并不知道方法的返回类型的地方(比如alloc),比如我们经常声明delegate为id类型,在运行的时候再使用respondToSelector:来进行检查。

2. id<NSObject>

使用id<NSObject>来声明一个对象,相当于告诉编译我们并不知道这个对象的类型,但是它实现NSObject protocol。一个这种类型的指针,即可以用来指向NSObject*对象,也可以用来指向NSProxy*对象,因为NSObject对象与NSProxy对象都是现了NSObject protocol。

3. id 与 instancetype

在instancetype有效的情况下,应该尽量去使用instancetype。至于什么是合适的时候,可以参考stack overflow上面所说:“Use instancetype whenever it‘s appropriate, which is whenever a class returns an instance of that same class.”,http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id/14652187#14652187

时间: 2024-10-29 10:46:57

id、NSObject *、id<NSObject>、instancetype的区别的相关文章

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

id 被成为万能指针,也就是可以指向任何对象. NSObject * 本身就是定义指向NSObject类型的指针. 那么这两者有什么区别吗? 这两者都是既可以作为返回值,又可以作为变量修饰.而其主要区别则在于id修饰的变量不遵循<NSObject>协议.这在实现代理模式中会体现出其区别,例如在调用代理方法时会先判断该代理是否能够响应某个方法  [obj respondsToSelector:]就定义在NSObject协议中. 那么,苹果后来为什么有使用instancType呢? 我觉得主要原因

IOS_OC_id ,NSObject, id&lt;NSObject&gt;区别

我们经常会混淆以下三种申明(我是没有留意过): 1. id foo1; 2. NSObject *foo2; 3. id<NSObject> foo3; 第一种是最常用的,它简单地申明了指向对象的指针,没有给编译器任何类型信息,因此,编译器不会做类型检查.但也因为是这样,你可以发送任何信息给id类型的对象.这就是为什么+alloc返回id类型,但调用[[Foo alloc] init]不会产生编译错误. 因此,id类型是运行时的动态类型,编译器无法知道它的真实类型,即使你发送一个id类型没有的

id 和 instancetype 的区别

1.什么是 instancetype?同 id 一样,都是表示未知类型的对象. 2.关联返回类型的方法根据 Cocoa 规则, 满足下列规则的方法:1.类方法中,以 alloc 或 new 开头.2.实例方法中,以 autorelease,init,retain或 self 开头的这些方法,会返回一个所在类类型的对象,这些方法就被称为是关联返回类型的方法.以代码为例:@interface NSObject+ (id)alloc;- (id)init;@end @interface NSArray

IOS_OC_id ,NSObject, id&amp;lt;NSObject&amp;gt;差别

我们常常会混淆下面三种申明(我是没有留意过): 1. id foo1; 2. NSObject *foo2; 3. id<NSObject> foo3; 第一种是最经常使用的,它简单地申明了指向对象的指针,没有给编译器不论什么类型信息,因此,编译器不会做类型检查.但也由于是这样,你能够发送不论什么信息给id类型的对象.这就是为什么+alloc返回id类型,但调用[[Foo alloc] init]不会产生编译错误. 因此,id类型是执行时的动态类型,编译器无法知道它的真实类型,即使你发送一个i

$arr[&#39;id&#39;],$arr[id]的区别

说白了区别就是当不加''的时候我们首先会考虑的是这个id是不是一个常量 例如: define("abc",'ABC'); 那么实际上$arr[id] = $arr['ABC']; 所以在这个过程中就会多加了一步操作.那么引申一个问题就是 在$arr取值时尽量使用单引号就会比直接写或者加双引号就会更快一些. $arr['id'],$arr[id]的区别

android:id=&quot;@android:id/tabhost&quot; 、android:id=&quot;@+id/llRoot&quot; 、android:id=&quot;@id/llRoot&quot; 之间的区别

由于快要放暑假了,所以最近这俩周把Android方面的知识复习一下,准备找个实习工作. 顺便把自己的总结更大家分享一下,共同进步,谢谢.... 一. android:id="@android:id/tabhost"   是调用系统内部的ID 和代码中 mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent); 是一回事. 二. android:id="@+id/llRoot&q

Android中@id与@+id区别

近日升级adt21+后,在输出apk时碰到编译layout异常,看了下是因为有人在layout引用一个不存在的resID时用了 @+id/xxx,而不是@id/xxx,导致debug编译器没显示错误,而在打包时的编译器出现错误,adt21-则没有此问题. 附上配图说明: Android中@id与@+id区别 : Android中的组件需要用一个int类型的值来表示,这个值也就是组件标签中的id属性值. id属性只能接受资源类型的值,也就是必须以@开头的值,例如,@id/abc.@+id/xyz等

id、name、class的区别

HTML 中 id与name 区别 一个name可以同时对应多个控件,比如checkbox和radio 而id必须是全文档中唯一的 1)id的用途  (1)  id是HTML元素的Identity,主要是在客户端脚本里用. (2) label与form控件的关联,如 <label for="MyInput">My Input</label>            <input id="MyInput" type="text&q

Android @id和@+id区别

Android中的组件需要用一个int类型的id属性值来表示.id属性只能接受资源类型的值,也就是必须以@开头的值,例如,@id/abc.@+id/xyz等.如果在@后面使用"+",表示当修改完某个布局文件并保存后,系统会自动在R.java文件中生成相应的int类型变量.变量名就是"/"后面的值,例如,@+id/xyz会在R.java文件中生成int xyz = value,其中value是一个十六进制的数.如果xyz在R.java中已经存在同名的变量,就不再生成新

$(&quot;#id&quot;)与$(&#39;input[name=&quot;nameId&quot;]&#39;)的区别

今日在用easyUI的numberbox控件时遇到一个问题: 我在页面中定义了一个输入框: <input id="yesId" name="yesName" value="yes" ></input> 使用jquery选择器获取这个输入框时,有两种方法 var a = $("#yesId"); var b = $('input[name="yesName"]'); alert(a =