0

I had an interview, and I was asked to create a memory leak with Objective-C and Swift.So how to create a memory leak with Objective-C and Swift?

Henson Fang
  • 1,177
  • 7
  • 30
  • Just go throught the link about how to create a memory leak and how to avoid memory leak https://www.raywenderlich.com/134411/arc-memory-management-swift – Anil Kumar Mar 24 '17 at 08:02

3 Answers3

7

You just need to create a reference cycle. Obj-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;

The same applies to Swift:

class MyClass {
    var otherObject: MyClass?
}

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

Reason: a holds a strong reference to b, and b holds a strong reference to a. ARC doesn't have any garbage collection in runtime. It just tracks the reference count. In this situation, even if we don't have any references to a or b in code, their reference count will never reach 0, since they reference each other (unless we'll break this cycle manually).

UPD (kudos to @Sulthan): you don't actually even need two objects, a strong self reference is enough:

a.otherObject = a
gran_profaci
  • 8,087
  • 15
  • 66
  • 99
FreeNickname
  • 7,398
  • 2
  • 30
  • 60
  • If you want a minimal example, you can just assign `a.otherObject = a`. – Sulthan Mar 24 '17 at 08:14
  • True answer.I think strong refrence in block may also cause memory leak?But sometimes the complier warns me about the memory leak in block,sometimes not,I was confused then. – Henson Fang Mar 24 '17 at 08:19
  • @HensonFang It can but that's just a more complicated instance of this example. – Sulthan Mar 24 '17 at 08:28
  • @HensonFang, yes, in some cases. If you're using GCD, then, most likely, everything will be fine, since GCD doesn't store a reference to your object. But if, for instance, you have an `NSOperationQueue`, and you create an operation with block, that references `self`, then your `self` has a reference to queue, the queue has a reference to operation, operation to block, and block to self. – FreeNickname Mar 24 '17 at 12:22
  • Good answer. I tossed a block example in for kicks. – bbum Mar 26 '17 at 16:52
2

The block example:

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

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

The fix:

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];
};

The malloc example:

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

  ...
 leakVampires();
bbum
  • 162,346
  • 23
  • 271
  • 359
-1

If CGImageRef objected created and not released, then ARC can't release these objects.