在iOS 3.0问世时,我做了一些iOS
开发,但两年来我一直不知道iOS的进展如何。
我记得你会在iOS
3.0中保留,即使如此,我仍然不记得保留二传手的确切原因是什么。到目前为止,这只是困扰我的一件事。
最后但同样重要的是,在带有ARC的iOS 5中,局部变量默认情况下是强的。如果其中一些变量没有setter,它们怎么会强呢?(举个例子,同上)
一些代码来解释我的意思:
+(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;
}
您可以在编译时向对象发送消息,而不知道它们的确切类型。事实上,当您向从数组返回的对象发送消息时,您通常会这样做:您不需要将id
强制转换为确切的类型,只需发送一条消息,Objective C就会正确地调度它。此规则的唯一例外是使用点.
语法访问属性:您确实需要进行强制转换。
类从NSObject
继承的每个对象都响应retain
、release
、autorelease
等等。这就是ARC需要知道的全部。在最坏的情况下,如果您的id
恰好指向无效的东西,您将收到"对象不响应选择器"消息。
您似乎混淆了属性与实例变量和局部变量。
变量没有setter属性有setter。任何类型的属性都可以有setter(可能为void的除外)。实例变量可能恰好对应于属性,但变量本身没有"setter"。obj->ivar
永远不会调用setter,即使在ARC下也不会。。
ARC只做大约三件事:
-
为您插入
retain
、release
、autorelease
和dealloc
。当你写// ARC { id foo = [array lastObject]; ... }
它被翻译成近似
// MRC { id foo = [[array lastObject] retain]; ... [foo release]; }
它使用Objective-C命名约定来确定需要保留和发布什么。有一些优化(由于ARC规范中描述的原因,它实际上使用了
objc_retain()
和friends,另外还有一些功能可以比-autorelease
更有效地处理自动发布的对象。) -
在
-dealloc
中为您发布__strong
ivars。它不调用属性设置器;它只是释放了ivar。它还可能将它们设置为nil
。 -
将弱引用归零。CCD_ 21变量是与CCD_ 22和朋友一起读/写的,而不是直接访问。
-[NSObject release]
(大约)中还有一个钩子,以便正确地实现弱引用归零。
此外,围绕块和__block
变量的语义以一种不容易通过MRC复制的方式进行更改。除此之外,我相信ARC所做的一切都可以通过调用ARC运行时支持函数调用来复制。
ARC和setter之间的唯一联系是可以去掉很多属性,因为编译器在ivar访问时插入retain/release。