Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.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
Ios 未解除分配的闭包变量_Ios_Objective C_Xcode_Memory Management_Swift - Fatal编程技术网

Ios 未解除分配的闭包变量

Ios 未解除分配的闭包变量,ios,objective-c,xcode,memory-management,swift,Ios,Objective C,Xcode,Memory Management,Swift,对我来说,描述这个问题最简单的方法就是用一个小例子来说明 //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 a swift file

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

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

}

myObjectiveCObject.startParsing()



每次闭包调用分配的内存直到我处理完objective-c对象后才会释放。当然,预期的行为是在每次闭包调用后释放内存?

如果实例化autorelease对象,但不定期耗尽autorelease池,则可能会出现这种问题。通常,直到您返回到运行循环(或操作或分派的任务完成),池才会被排空。因此,您必须始终非常小心循环数千次。(请参阅的“使用本地自动释放池块减少峰值内存占用”部分。)

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

- (void)startParsing {

    // loop around thousands of times

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

            self.callbackBlock(someNewObject)
        }
    }    
}
有一个等价的Swift函数,毫不奇怪地称为
autoreleasepool()
,因此如果您知道autorelease对象是由闭包创建的东西创建的,您也可以在那里处理它。如果没有看到代码或在工具中分析它,很难猜测是哪个创建了autorelease对象。(请注意,是的,我知道本机Swift对象通常不会自动删除,但您无法保证Swift闭包调用的任何代码,这就是Swift提供
autoreleasepool
功能的原因。)

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


显然,在处理大型循环时,除了自动释放对象(例如,在内存中同时持有过多大型资产(图像等)、递归调用函数等)之外,还有其他导致此类内存问题的原因。但是我想你已经检查过你的代码了。因此,自动释放对象是另一件需要检查的事情。

否。循环“数千次”将调用该块的数千次,该块将使用数千个相同的分配对象数千次加载相同的变量,并将数千个相同的帧推送到堆栈上。你才是需要在记忆力方面更加保守的人@那么,从设计层面来看,我如何解决这个问题呢?使用解析块非常优雅。有没有办法解决记忆问题?很有魅力。感谢您的深入描述,非常感谢。先生,您能帮我理解为什么会发生这种情况吗!!
- (void)startParsing {

    // loop around thousands of times

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

            self.callbackBlock(someNewObject)
        }
    }    
}