不确定这个问题是否过于宽泛,在这种情况下,你可以用更为一般的先例解释并提供一些例子。
答案 0 :(得分:2)
根据您的标签判断,我将专门回答ARC。
当部分代码不恰当地创建强引用时,对象通常会被过度保留。
例如,过度保留的常见方式是两个对象之间是否具有强引用。强引用可防止对象被释放 - 在两个对象以这种方式相互引用的情况下,则创建一个循环,这意味着在另一个对象出现之前都不会被释放。
另一个例子是使用块作为变量。假设一个对象有一个实例块变量/属性,其中包括:
self.blockProperty = ^{
self.property = value;
};
这会在块内为对象本身创建一个强引用。这里正确的做法是创建一个对self
的弱引用并在块中使用它,但这种细微之处常常容易被忽视。
另一方面,当相反的情况发生时,对象通常是过度释放,即当代码具有对实际依赖的对象的弱引用时。这可能意味着在仍然需要时对象被释放。或者,该对象可能无意中被设置为nil
,或者可能从未首先启动过。
这些问题(根据我的经验)在使用ARC时不那么常见,但这并不意味着你可以忘记它们。良好的分析工具的使用有助于挑选前者,并且您通常会知道后者是什么问题,因为您将看到EXC_BAD_ACCESS
或类似的,这总是很有趣的调试。但是,由于弱引用在其目标被释放时设置为nil
,因此不会总是如此,因此当您尝试向其发送消息时,您可能无法获取错误。< / p>
答案 1 :(得分:1)
过度发布当对象收到的消息多于release
消息时发生<{1}}消息,也就是说,当最后retain
消息发送到release
消息时,它已被解除分配它。结果通常是崩溃或未定义的行为。
Overretain 表示您的代码中有一个retain
从未与release
(忘记release
某处)配对,该对象从未被释放。创建了自动释放池和autorelease
消息以防止 overretain 。结果通常是应用程序需要太多内存,但用户不会注意到错误是否多次重复。
当然,这只能在手动参考计数(MRC)下进行,因为在自动参考计数(ARC)下,您永远不会手动发送retain
或release
。
在对象使用手动引用计数(例如Core Foundation对象)时,有一些特定情况,您必须使用__bridge
强制转换才能在ARC下使用它们。如果您错误地使用桥接模型,可能会出现类似的问题。我不确定这个名称是overrelease
还是overretain
。
顺便说一下,不要把保留周期混淆得过多。这是一个不同的错误,在MRC和ARC下有不同的解决方案。
答案 2 :(得分:-1)
在ARC环境下,仅在__bridge_transfer
和__bridge_retained
强制转换时发生过度释放和过度保留(Core Foundation提供与CFBridgingRelease
和CFBridgingRetain
相同的功能)。
过度释放:
NSObject *obj = (__bridge_transfer NSObject*)(__bridge void*)[[NSObject alloc] init];
过保留:
NSObject* obj = (__bridge NSObject*)(__bridge_retained void*)[[NSObject alloc] init];