当iOS 3.0问世时,我做了一些iOS
开发,但两年后我忘记了iOS的运作方式。
我记得你会留在iOS
3.0中,即便如此,我仍然不记得保留在制定者中的原因是什么。到目前为止,这只是让我感到困惑的一件事。
最后但并非最不重要的是,在iOS 5中使用ARC默认局部变量很强。如果他们中的一些人没有制定者,他们怎么能够坚强? (例如,id。)
一些代码来解释我的意思:
+(double) popOperandOffStack:(NSMutableArray *) stack{
double result = 0;
id topOfStack = [stack lastObject];
// how is topOfStack retaining [stack lastObject] if it's simply id?
if (topOfStack) [stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]]){
result = [topOfStack doubleValue];
}
else if ([topOfStack isKindOfClass:[NSString class]]){
if ([topOfStack isEqualToString:@"+"]){
result = [self popOperandOffStack:stack] + [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"-"]){
result = [self popOperandOffStack:stack] - [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"*"]){
result = [self popOperandOffStack:stack] * [self popOperandOffStack:stack];
}
if ([topOfStack isEqualToString:@"/"]){
result = [self popOperandOffStack:stack] / [self popOperandOffStack:stack];
}
}
return result;
}
答案 0 :(得分:2)
您可以在编译时向对象发送消息,而无需知道其确切类型。实际上,当您向从数组中返回的对象发送消息时,通常会这样做:您不需要将id
强制转换为确切的类型,只需发送消息,然后Objective C将正确地发送消息。此规则的唯一例外是使用点.
语法访问属性:您需要在那里进行转换。
其类继承自NSObject
的每个对象都会响应retain
,release
,autorelease
等。这就是ARC需要知道的全部内容。在最坏的情况下,如果你所遇到的id
碰巧指向无效的东西,你将会得到“一个对象不响应选择器”的消息。
答案 1 :(得分:1)
您似乎将属性与实例变量和局部变量混淆。
变量没有setter。属性有setter。 任何类型的属性可以有setter(可能无效)。实例变量可能碰巧对应于属性,但变量本身没有“setter”。 obj->ivar
永远不会打电话给安装人员,甚至不在ARC 之下。
ARC只做了大约三件事:
为您插入retain
,release
,autorelease
和dealloc
。当你写
// ARC
{
id foo = [array lastObject];
...
}
它被翻译成大约
// MRC
{
id foo = [[array lastObject] retain];
...
[foo release];
}
它使用Objective-C命名约定来确定它需要保留和释放的内容。有一些优化(实际使用objc_retain()
和朋友出于ARC spec中描述的原因,再添加一些函数来比{{1}更有效地处理自动释放的对象}。)
在-autorelease
为您发布__strong
个ivars。它没有打电话给财产制定者;它只是释放了伊娃。它也可能将它们设置为-dealloc
。
归零弱引用。nil
变量使用__weak
和朋友读取/写入,而不是直接访问。在objc_copyWeak()
(或左右)中还有一个钩子,以便正确实现归零弱引用。
此外,围绕块和-[NSObject release]
变量的语义以不易通过MRC复制的方式进行更改。除此之外,我相信通过调用ARC运行时支持函数调用可以复制ARC所做的一切。
ARC和setter之间的唯一连接是你可以摆脱很多属性,因为编译器在ivar访问时插入了retain / release。