i want to make a weak pointer to self in swift like how we used to in objective-c like
__weak Something *weakself = self;
I have found people explaining how to use a 'weak self' inside a block,
{ in [unowned self] ...}
but i dont want to define 'weakself' inside my block, i want to define weakself outside of blocks
[weak self] Example in Swift To do this it has to access the elapsedTime property of the StopWatch class via self. This creates a strong reference to self from the closure. But the timer is also automatically strongly referenced by the StopWatch class (or self).
because block are mean to be executed at a later time, so it need to keep strong reference to all the object it access. Block can be executed MANY TIMES, so IT WON'T RELEASE self AFTER this ran. When you nil out the block, it will be dealloc, hence it will decrease the reference count to all the objects it access.
“Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialisation.” Save this answer.
In Swift, we need to use weak self and unowned self to give ARC the required information between relationships in our code. Without using weak or unowned you're basically telling ARC that a certain “strong reference” is needed and you're preventing the reference count from going to zero.
Just define a weak reference with the weak
keyword:
weak var weakSelf = self
From the documentation:
You indicate a weak reference by placing the
weak
keyword before a property or variable declaration.
...
NOTE: Weak references must be declared as variables, to indicate that their value can change at runtime. A weak reference cannot be declared as a constant.
It sounds to me like you're trying to avoid a retain cycle with a block like you do in Objective-C, where instead of referencing self, you create a weak version:
__weak MyType *weakSelf = self; void (^aBlock)() = ^void() { [weakSelf doStuff]; }
That is not how Swift handles this problem.
Instead, it has the concept of a capture list, that tells the compiler which references the block captures, and what to do about it. You should search the Swift Programming Reference book for "Capture List" and read up on the subject. To quote the book:
“If you assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles. For more information, see Strong Reference Cycles for Closures.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
To quote the part of the Swift book that explains how to create a capture list:
Defining a Capture List: Each item in a capture list is a pairing of the weak or unowned keyword with a reference to a class instance (such as self) or a variable initialized with some value (such as delegate = self.delegate!). These pairings are written within a pair of square braces, separated by commas.
Place the capture list before a closure’s parameter list and return type if they are provided:
lazy var someClosure: (Int, String) -> String = { [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in // closure body goes here }
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2).” iBooks. https://itun.es/us/jEUH0.l
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With