我目前正在为 iOS 开发一款游戏,而且我们有内存泄漏。我们的项目是 ARC 设置。我想知道如何确保内存释放。我想要采取的步骤之一是转换形式的代码:
-(void)methodMethod{
Object* o = [[Object alloc] init];
// Some logic
}
成:
-(void)methodMethod{
Object* o = [[Object alloc] init];
// Some logic
o = nil; // Explicit nil assignment
}
这两者有区别吗?我应采取哪些其他措施来确保ARC设置中的dealloc?
我们正在使用Sparrow Framework。
答案 0 :(得分:3)
两种方法都做同样的事情。当它们离开范围时,本地对象被ARC设置为nil,因此放入手动nil什么都不做。
如果你想找到一个泄漏 - 你最好通过使用Leaks工具的仪器运行它并找出泄漏的东西,这将使你更好地了解发生了什么。找到保留周期非常方便。
答案 1 :(得分:2)
正如Abizem指出的那样,这两种方法都会产生相同的结果,需要仔细通过仪器。结果并不总是易于理解。
在ARC中,你永远不应该看到泄漏 - 用通常的obj-C意思 - 。有时,iOS工具可以报告泄漏,但大多数(如果不是全部),这来自运行时,我倾向于将它们视为超出我的控制。然而,你可以看到的是不受控制的内存增加,这是内存保留的典型特征。保持对象的强大指针是显而易见的原因,在我的情况下一直是以下结果:保留代码块中的循环,以及不正确的数据结构清理,即创建对象,然后填充到数组,字典,页面控件等。但是在应用程序生命周期中,后者没有正确清空。
此外,图像处理函数仍然使用嵌入到内部UIGraphics lib中的标准malloc / free指令,因此在这种情况下你明确需要释放内存(CGImageRelease等等)。 ARC在这里没有帮助。
希望这有助于缩小问题的范围,正如Abizem指出的那样,应该从仪器开始。
答案 2 :(得分:0)
将方法包装在@autoreleasepool中。这将使99%的百分比确定它被解除分配
-(void)methodMethod{
@autoreleasepool {
Object* o = [[Object alloc] init];
// Some logic
}
}
答案 3 :(得分:0)
两者都是一样的。
测试课程的更好解决方案:
- (void)testDealloc
{
__weak CLASS *weakReference;
@autoreleasepool {
CLASS *reference = [[CLASS alloc] init]; // or similar instance creator.
weakReference = reference;
// Test your magic here.
[...]
}
// At this point the everything is working fine, the weak reference must be nil.
XCTAssertNil(weakReference);
}
这可以为我们想要在@autorealase
内部解除分配的类创建一个实例,一旦我们退出该块,它就会被释放(如果我们没有泄漏)。 weakReference
将保留对实例的引用而不保留它,该引用将设置为nil
。