Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 过度释放或过度保留是如何发生的?_Objective C_Automatic Ref Counting_Release_Retain - Fatal编程技术网

Objective c 过度释放或过度保留是如何发生的?

Objective c 过度释放或过度保留是如何发生的?,objective-c,automatic-ref-counting,release,retain,Objective C,Automatic Ref Counting,Release,Retain,不确定这个问题是否太宽泛,如果是这样的话,你能用一个更一般的句子来解释,或者举一些例子。根据你的标签判断,我将专门回答ARC 当代码的某些部分不适当地创建对对象的引用时,对象通常会被过度保留 例如,发生过度保留的常见方式是两个对象彼此具有强引用。强引用防止对象被解除分配-如果两个对象以这种方式相互引用,则会创建一个循环,这意味着在另一个对象被解除分配之前,任何一个对象都不能解除分配 另一个例子是当使用块作为变量时。假设一个对象有一个实例块变量/属性,其中包括以下内容: self.blockPro

不确定这个问题是否太宽泛,如果是这样的话,你能用一个更一般的句子来解释,或者举一些例子。

根据你的标签判断,我将专门回答ARC

当代码的某些部分不适当地创建对对象的引用时,对象通常会被过度保留

例如,发生过度保留的常见方式是两个对象彼此具有强引用。强引用防止对象被解除分配-如果两个对象以这种方式相互引用,则会创建一个循环,这意味着在另一个对象被解除分配之前,任何一个对象都不能解除分配

另一个例子是当使用块作为变量时。假设一个对象有一个实例块变量/属性,其中包括以下内容:

self.blockProperty = ^{
    self.property = value;
};
这将在块内创建对对象本身的强引用。这里正确的做法是创建一个对
self
的弱引用,并在块中使用它,但其微妙之处往往容易被忽略

另一方面,当相反的情况发生时,对象通常被过度释放,也就是说,当代码对它实际上所依赖的对象具有弱引用时。这可能意味着该对象在仍然需要时被解除分配。或者,该对象可能被无意中设置为
nil
,或者它可能从未启动过


在我的经验中,这两个问题在使用ARC时不太常见,但这并不意味着你可以忘记它们。良好地使用分析工具有助于选择前者,并且您通常会知道后者何时会出现问题,因为您将看到
EXC\u BAD\u ACCESS
或类似的情况,这对于调试来说总是很有趣的。然而,情况并非总是如此,因为当弱引用的目标被解除分配时,它们会被设置为
nil
,因此,当您尝试向它们发送消息时,您可能不会发现错误。

在ARC环境下,过度释放和过度保留只发生在<>代码>桥接传输> <代码> >代码>桥接器 CaseStudio(核心基础与代码提供了相同的功能.CFBRGGIGUP 和<代码> CFBridgingRetain < /代码>) 过度释放:

NSObject *obj = (__bridge_transfer NSObject*)(__bridge void*)[[NSObject alloc] init];
超额保留:

NSObject* obj = (__bridge NSObject*)(__bridge_retained void*)[[NSObject alloc] init];
当对象收到的
release
消息多于
retain
消息时,会发生超释放,也就是说,当最后一条
release
消息发送给对象时,该对象已被解除分配。结果通常是崩溃或未定义的行为

Overretain表示您的代码中有一个
retain
,它从未与
release
配对(忘记了
release
),对象从未解除分配。创建自动释放池和自动释放消息以防止过度释放。结果通常是应用程序需要太多内存,但如果错误没有重复多次,用户可能不会注意到

当然,这只能在手动参考计数(MRC)下发生,因为在自动参考计数(ARC)下,您永远不会手动发送
retain
release

当对象使用手动引用计数(例如核心基础对象)时,有一些特定的情况,您必须使用<代码>π桥接器>代码>在ARC下使用它们。如果不正确地使用桥接强制转换,可能会出现类似的问题。我不确定这是否属于
overrelease
overrelease
的名称


顺便说一句,不要把过度转换和保留周期混淆起来。这是一个不同的错误,在MRC和ARC下有不同的解决方案。

不要将过度调整与保留周期混淆。好的,在ARC的上下文中,这本质上就是它的意思。与中一样,对象被过度保留。但我同意,这意味着如果是这样的话,MRCIt会有很大的不同,但是(从Xcode 8.0开始)不是这样。在纯Swift中,我仍然可以得到超出范围的错误,而无需任何桥接。这些可能是编译器错误的结果,但这只是强调开发人员仍然需要理解内存模型,不能相信编译器总是保存它们!