我们正在开发一款我们想在iOS 4.3及更高版本上运行的应用。
我们的高级开发人员认为使用ARC是一件坏事,会导致iOS 5以下的任何事情发生崩溃和问题。这是真的吗?在iOS 4.3上使用ARC时会出现什么问题?
我知道你必须使用unsafe_unretained而不是弱引用。这可能导致什么问题?
如果我们也在为iOS 4.3开发,我们是否应该根本不使用ARC?或者是否可以使用ARC为iOS 5及以上版本和iOS 4.3开发可靠的应用程序?
答案 0 :(得分:6)
在部署到4.x时,没有理由不使用ARC。说完ARC导致iOS 5以下的任何事情都出现崩溃和问题是完全错误的。这完全忽略了这一点而不理解ARC可能是什么。
ARC是一个编译时间“funkiness”。无论如何,这就是我喜欢的名字!它只是添加了正确数量的保留和释放或自动释放,以使您的对象保持在他们应该的长度。我喜欢将其视为将对象转换为堆栈变量。所以请考虑以下代码:
- (void)methodA {
NSNumber *number = [[NSNumber alloc] initWithInt:5];
[someObject doSomethingWithANumber:number];
}
当release
变量超出范围时,ARC将添加number
number
。在这种情况下,当methodA
返回时,它超出范围。所以考虑一下这个更精细的代码:
- (void)methodB {
NSNumber *number = [[NSNumber alloc] initWithInt:5];
if (<some_expression>) {
return;
}
[someObject doSomethingWithANumber:number];
}
在这种情况下,如果没有ARC,我们将不得不进行2次[number release]
次呼叫。一旦提前返回,一次在方法结束时。显然这是一个人为的例子 - 它只是为了展示这个想法。使用ARC,我们不必为它们提供这两个调用。我认为你可以在这看到ARC的强大功能,因为在这种情况下如果你的方法变得更大更复杂,你很容易忘记在从方法过早返回之前释放东西。
回到关于4.x的观点......你是对的,你不能使用weak
引用。这是因为这是ARC中唯一需要运行时帮助的部分,而这不是4.x附带的运行时的一部分。当指向的对象消失时,运行时将自动清零弱引用。因此,如果ObjectA具有对ObjectB的弱引用(例如委托模式),那么如果ObjectB因为不再使用而消失,那么ObjectA的引用将被填充。在我看来,这只是一个安全网。您应该进行编码,以便无论如何都会发生从不的情况。自从弱引用出现之后,它就一直是这样的,你只需要以不让它成为问题的方式进行编码 - 我们已经做了很多年了。
在我看来,你应该使用ARC。它会对你有所帮助。您将获得更小的代码和更易读的代码,因为您没有代码中的保留,发布和自动释放。你会减少崩溃和不正确的内存管理泄漏,我们所有都遇到了问题。
简而言之:使用ARC。
答案 1 :(得分:0)
我非常同意,它们与在iOS4中使用assign相同,但是为了表明它们不太可能导致崩溃,在这种情况下并没有考虑到这一点。谁编写代码使其崩溃?没有人。尽管有此意图,应用程序仍会崩溃吗当然。在各种罪犯中隐约可见的是记忆管理和ARC的存在理由。有趣的是,虽然iOS开发人员最不谨慎的做法是分配 - 而且这就是危险所在。你经常看到代码和数据源没有在dealloc中归零的代码吗?由于我们对清洁的代码感到高兴,并且不考虑悬挂指针的危险,因此在ARC中处理这些问题时的谨慎程度将会增加。 iOS4中的这种风险并不明显,并且很难追踪。
ARC是前进的方向,但有充分理由支持iOS4中的应用程序采取经过深思熟虑的方法。
答案 2 :(得分:-1)
这是不正确的。在iOS4中,运行时不会自动使弱引用无效,只能使用__unsafe_unretained(非归零)而不是__weak(归零),这可能导致崩溃。这里有一些有用的背景知识:
http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html
http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html