how to make a weak pointer to self in swift outside of a block
Asked Answered
A

2

24

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

Angle answered 19/4, 2015 at 21:13 Comment(2)
In what context do you need a weak reference to self, if not in the context of blocks/closures? If you want a delegate property to be weak, for example, you'd just declare it as such (e.g. weak var delegate: MyProtocol! or whatever).Nutcracker
@Nutcracker has a good point. In what context could code in one of an object's methods be running if self did not exist? You need an object to run methods on.Somaliland
P
67

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.

Penley answered 19/4, 2015 at 21:19 Comment(1)
For once this line of code is actually better-looking than in Objective-C. Thanks! :)Penneypenni
T
9

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

Edited 4 Jan 2016:

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

Thrashing answered 19/4, 2015 at 21:53 Comment(2)
Thanks Duncan. The doc is also here. Look for "Resolving Strong Reference Cycles for Closures".Yucca
I love how swift is much more simpler than any other language on the Klingon domain. /s> Swift is satan's masterpiece.Subalpine

© 2022 - 2024 — McMap. All rights reserved.