问题描述
我知道当我们想创建一个未知的值对象时,我们使用id。然而,我很好奇为什么苹果选择id,它决定了它的价值在运行时,当每个对象是NSObject的子类。所以代替 id委托
我们可以使用 NSObject * delegate
有没有人知道为什么?感谢。
I know that when we want to create an unknown value object we use id. However, I'm curious that why did Apple to choose id which decides it's value during runtime, when every object is a subclass of NSObject. So instead of id delegate
we could have used NSObject *delegate
Does anyone know why? Thanks.
推荐答案
id
擦除类型, 此对象响应翻译可见的任何选择器。当然,当您清除类型时(以及在您输入类型时),是您的责任,以确保您的程序正确。
id
erases the type and it is equivalent to saying "this object responds to any selector visible to the translation". of course, it is your responsibility to make sure your program is correct when you erase types (and also when you typecast them).
类型是 NSObject
,那么如果选择器未在NSObject的接口或协议中声明,编译器会说NSObject可能不响应 它采用。在这种情况下,你还可以添加一个类型转换来将它转换为你期望的类型。
If the type were NSObject
, then the compiler would say "NSObject may not respond to selector" if the selector was not declared in NSObject's interface or the protocols it adopts. In that event, you could also add a typecast to cast it to the type you expect.
使用严格/正确的类型,编译器可以帮助你,这是非常好的,因为ObjC是一个非常动态的语言。
With strict/correct types, the compiler can kick in and help you out, which is great because ObjC is a very dynamic language.
id
类型。添加一个对象不会是一个问题,除非你定义了一个新的根类型(不继承NSObject)。从集合中获取值需要一个类型转换,如果我们使用它作为除了我们的基类(NSObject)之外的东西。
id
is particularly useful when using (or building) collections types. Adding an object would not be a problem unless you defined a new root type (does not inherit from NSObject). Getting a value from the collection would require a typecast if we were to use it as something other than our base class (NSObject).
Objective-C不支持泛型 - 你不能,例如,声明 NSArray
的 NSString
s。您可以使用 NSString
填充 NSArray
,并将其传递到 id $ c $
Objective-C does not support generics - you cannot, for example, declare an NSArray
of NSString
s. You can populate an NSArray
with NSString
s and pass this through id
for a more natural written style when type safety is not preserved (a la generics).
因此,让我们用一些真正的代码展开这个。
So, let's expand on this with some real code.
示例A
NSString * string = [array objectAtIndex:0]; // << trust me (via id)
return [string length];
-or-
return [[array objectAtIndex:0] length]; // << trust me (via id)
示例B
现在让我们说 id
不可用,我们修复所有的编译器警告,因为它是正确的事情:
And now let's say id
is not available and we fix all our compiler warnings because it's the right thing to do:
NSString * string = (NSString*)[array objectAtIndex:0]; // << typecast == trust me
return [string length];
-or-
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me
id
在运行时决定它的值,也没有任何NSObject。
id
doesn't decide its value at runtime, nor doe any NSObject. ObjC objects don't perform implicit promotions, they just cast the pointer through without formal promotion.
与你的例子相关,我实际上声明我的委托和参数为NSObjects与协议:
Related to your example, I actually declare my delegates and parameters as NSObjects with protocols:
NSObject<MONShapeDelegate>* delegate;
这篇关于为什么使用id,当我们可以只使用NSObject?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!