gpt4 book ai didi

ios - 关闭变量不释放

转载 作者:可可西里 更新时间:2023-11-01 02:27:33 27 4
gpt4 key购买 nike

对我来说描述问题的最简单方法是用一个小例子来展示。

//In a swift file

myObjectiveCObject.setCallbackBlock {(object: AnyObject!) -> Void in

var chunkOfMemory = //fill up var with memory stuff. Self is never referenced.

}

myObjectiveCObject.startParsing()


//In the objective-c class file

@property (nonatomic, copy) MyBlockType callbackBlock;

- (void)startParsing {

//loop around thousands of times calling
self.callbackBlock(someNewObject)

}


在我完成 objective-c 对象之前,从每个闭包调用分配的内存不会被释放。肯定预期的行为是在每次关闭调用后释放内存?

最佳答案

如果实例化自动释放对象,但不定期耗尽自动释放池,就会出现此类问题。通常,在您返回运行循环(或操作或分派(dispatch)的任务完成)之前,池不会被耗尽。因此,您必须始终非常小心地循环数千次。 (请参阅 Advanced Memory Management Programming Guide: Using Autorelease Pool Blocks使用本地自动释放池 block 减少峰值内存占用部分。)

通常通过创建(并因此耗尽)您自己的本地自动释放池来控制此峰值内存使用量:

- (void)startParsing {

// loop around thousands of times

for ( ... ) {
@autoreleasepool {
// do whatever

self.callbackBlock(someNewObject)
}
}
}

还有一个等效的 Swift 函数,毫不奇怪,它也称为 autoreleasepool(),所以如果您知道自动释放对象是由您的闭包创建的对象创建的,您也可以在那里处理它。如果不在 Instruments 中查看或分析代码,很难猜测是哪个创建了 autorelease 对象。 (请注意,是的,我知道原生 Swift 对象通常不会自动释放,但您不能保证 Swift 闭包调用的任何代码,这就是 Swift 提供 autoreleasepool 函数的原因。)

如果你真的想诊断这个,你可以在 Instruments 中运行它,并在 startParsing 完成之前暂停它,并查看尚未发布的内容,然后回溯到那些对象的位置被实例化,这将帮助您诊断自动释放对象的创建位置,从而确认您需要在何处添加池。

显然,在处理大型循环时,除了自动释放对象(例如,同时在内存中保存过多大型资源(图像等),递归调用函数)之外,还有其他类型的内存问题来源, ETC。)。但我假设您已经检查过您的代码以了解任何类似的明显问题。所以自动释放对象是另一件要检查的事情。

关于ios - 关闭变量不释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26498822/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com