Use*_*321 9 xcode pointers objective-c void-pointers ios
我想知道为什么id是弱引用指针,它如何处理任何class类型指针,在运行时我们如何检测分配给哪种类型的类指针id.
小智 17
为什么id是弱引用指针?
id不是弱引用指针,至少不是ARC所有权意义上的指针.是否id-typed的对象引用较弱或不依赖于已被宣布为参考__weak(和变化)和对象的类实际上支持弱引用.
但是,你可以说这id提供弱类型,虽然我认为动态/鸭子打字是一个更准确的描述.由于id- 类型引用不包含编译时类类型信息,因此编译器无法确定底层对象是否可以响应给定的选择器,这可能导致运行时错误.
它如何处理任何类类型指针?
这是Objective-C语言定义的一部分.编译器将其识别id为每个Objective-C类的超类型,并且它的处理方式id不同.请参阅下面的答案.
在运行时,我们如何检测分配给id的类指针类型?
在Apple的Objective-C运行时,分配给对象的内存中的第一个字节必须指向该对象的类.您可能会看到此引用的其他的isa指针,这就是苹果的运行时如何找出每类的1个对象.该id类型也被定义为具有此信息.实际上,它唯一的属性是isa指针,这意味着所有1个 Objective-C对象都符合这个定义.
如果您有一个id引用并想要发现引用对象的类,您可以发送它-class:
id someObject;
// Assign something to someObject
// Log the corresponding class
Class c = [someObject class];
NSLog(@"class = %@", c);
// Test whether the object is of type NSString (or a subclass of NSString)
if ([someObject isKindOfClass:[NSString class]]) {
NSLog(@"it's a string");
}
Run Code Online (Sandbox Code Playgroud)
1 标记指针是这种结构的显着偏差,并且(部分地)因为它们不应该isa直接访问指针.
拥有通用对象类型很好,因此您可以定义可以包含任何类型对象的集合类型,以及可以处理任何对象的其他通用服务,而无需知道它是什么类型的对象.
没有诀窍让id工作.在二进制级别,所有指针都是可互换的.它们只是将内存地址表示为数值.要使id接受任何类型的指针,只需要禁用通常需要指针类型匹配的编译器规则.
您可以通过以下方式找到有关id类型变量的类的信息:
id theObject = // ... something
Class theClass = [theObject class];
NSString *className = NSStringFromClass(theClass);
NSClassDescription *classDescription = [NSClassDescription classDescriptionForClass:theClass];
Run Code Online (Sandbox Code Playgroud)
但是很少有必要在代码中做这些事情.更常见的情况是,您希望测试您的id变量是否是特定类的实例,如果是,则将其强制转换为该类并开始将其视为该类型.
if ([theObject isKindOfClass:[MySpecializedClass class]]) {
MySpecializedClass *specialObject = (MySpecializedClass *)theObject;
[specialObject doSomethingSpecial];
}
Run Code Online (Sandbox Code Playgroud)
如果你是用来-class找出这个类的,但是它返回了一个你一无所知的类,那么你无论如何都无法根据它的类来对象.所以没有理由做任何事情,只要检查它是否与你知道的类匹配,并且只有你打算对这些类进行特殊处理.
你有时可以使用isMemberOfClass而不是isKindOfClass.这取决于您是想要完全匹配还是包含子类.