iosLearner iosLearner - 7 months ago 40
Swift Question

How memory leak will occur in swift?

I am new to ios development and i want to learn how memory leak will occur in

swift
or in
Objective-C
, can any one explain with small example?

Thanks

Answer

Small example:

class A {
    var b: B!

    deinit {
        print("deinit of A")
    }
}

class B {
    var a: A!

    deinit {
        print("deinit of B")
    }
}

do {
    let a = A()
    let b = B()
    a.b = b
    b.a = a
}

If you run this code (maybe in Playground), it will print nothing. It means that deinit never called for both objects and they just leaked.

But if you declare one of the properties as weak:

class A {
    weak var b: B!

    deinit {
        print("deinit of A")
    }
}

Then deinit will be called and you'll see messages in console.

Edit: add example with closures

Consider this example:

class C {
    var f: (Void -> Void)!

    deinit {
        print("deinit for C")
    }
}

do {
    let c = C()
    c.f = {
        print(c)
    }
}

c captures f, f captures c. So we got memory leak.

To deal with leaks in closures, you have 2 options – declare that captured object is weak or unowned. Like this:

do {
    let c = C()
    c.f = { [weak c] in
        print(c)
    }
}

Basically, you would use weak if it's possible for object to get out of existence and become nil when closure is called; but if you are sure object will still exist at this time, use unowned instead.

After I declare c as weak inside a closure, "deinit for C" is printed – means that everything deallocated successfully.

What this all means for you, the developer?

Almost all the time you don't have to worry about the memory management. It's done for you, automatically. Objects just exist when you need them and vanish when you don't. But there are 2 very common cases when you need to be careful and think about memory.

  1. Delegation. It's common pattern in Cocoa and it could create retain cycles if done wrong. Always declare your delegate as weak unless you have a good reason not to.
  2. Closures. Closure capture references for objects in surrounding scope and does it automatically, without notice. When implementing closure, chech if it will create retain cycle. If yes, declare problem variables as weak or unowned.

For further info I suggest you read official Apple Swift book which can be found in iBooks or here as a website.