23

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

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user1709076
  • 2,538
  • 9
  • 38
  • 59
  • 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). – Rob Apr 19 '15 at 21:20
  • @Rob 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. – rickster Apr 20 '15 at 02:20

2 Answers2

66

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
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

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thanks Duncan. The doc is also [here](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID56). Look for "Resolving Strong Reference Cycles for Closures". – Ferran Maylinch Mar 01 '16 at 14:39
  • 1
    I love how swift is much more simpler than any other language on the Klingon domain. /s> Swift is satan's masterpiece. – Duck Aug 28 '19 at 23:20