【问题标题】:Creat a memory leak with Objective-C and Swift使用 Objective-C 和 Swift 创建内存泄漏
【发布时间】:2017-08-17 01:49:12
【问题描述】:

我有一次面试,被要求用Objective-C和Swift创建内存泄漏。那么如何用Objective-C和Swift创建内存泄漏?

【问题讨论】:

标签: ios objective-c swift memory-leaks objective-c-runtime


【解决方案1】:

您只需要创建一个参考循环。 对象-C:

@interface MyClass : NSObject
@property (strong) MyClass *otherObject;
@end

@implementation MyClass
@end

//...

MyClass *a = [MyClass new];
MyClass *b = [MyClass new];
a.otherObject = b;
b.otherObject = a;

这同样适用于 Swift:

class MyClass {
    var otherObject: MyClass?
}

let a = MyClass()
let b = MyClass()
a.otherObject = b
b.otherObject = a

原因a 拥有对b 的强引用,b 拥有对a 的强引用。 ARC 在运行时没有任何垃圾收集。它只是跟踪引用计数。在这种情况下,即使我们在代码中没有任何对ab 的引用,它们的引用计数也永远不会达到0,因为它们相互引用(除非我们手动打破这个循环)。

UPD(感谢@Sulthan):实际上你甚至不需要两个对象,一个强大的自引用就足够了:

a.otherObject = a

【讨论】:

  • 如果你想要一个最小的例子,你可以分配a.otherObject = a
  • 正确答案。我认为块中的强引用也可能导致内存泄漏?但有时编译器会警告我块中的内存泄漏,有时不是,我当时很困惑。
  • @HensonFang 可以,但这只是这个例子的一个更复杂的例子。
  • @HensonFang,是的,在某些情况下。如果您使用 GCD,那么很可能一切都会好起来的,因为 GCD 不存储对您的对象的引用。但是,例如,如果您有一个NSOperationQueue,并且您创建了一个引用self 的块操作,那么您的self 具有对队列的引用,队列具有对操作的引用,对阻塞的操作,并阻止自己。
  • 好答案。我扔了一个块示例。
【解决方案2】:

方块示例:

@interface Foo:NSObject
@property(strong, copy) dispatch_block_t block;
- (void)doTheMagic;
@end

...
Foo *f = [Foo new];
f.block = ^{
   [f doTheMagic];
};

修复:

Foo *f = [Foo new];
__weak typeof(f) __weakF = f;
f.block = ^{
   // you can do the __strong dance here if you use __weakF more than once
   [__weakF doTheMagic];
};

malloc 示例:

void leakVampires() {
    void *buffy = malloc(42);
 }

  ...
 leakVampires();

【讨论】:

    【解决方案3】:

    如果 CGImageRef 对象已创建但未释放,则 ARC 无法释放这些对象。

    【讨论】:

    • 我认为viewcontroller dealloc时会自动释放。
    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 2013-05-23
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多