49

In Objective C you can define a property as having a strong or weak reference like so:

@property(strong)...
@property(weak)...

How is this done in swift?

67cherries
  • 6,931
  • 7
  • 35
  • 51

6 Answers6

67

Straight from the Swift Language guide:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { println("\(name) is being deinitialized") }
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
    deinit { println("Apartment #\(number) is being deinitialized") }
}

properties are strong by default. But look at the tenant property of the class "Apartment", it is declared as weak. You can also use the unowned keyword, which translates to unsafe_unretained from Objective-C

https://itunes.apple.com/tr/book/swift-programming-language/id881256329?mt=11

Sufian
  • 6,405
  • 16
  • 66
  • 120
Kaan Dedeoglu
  • 14,765
  • 5
  • 40
  • 41
12

A var is strong by default. You can add the weak keyword before a var to make it weak.

Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
11

Properties are strong by default, but if you want a weak property you can:

    weak var tenant: Person?

Source: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

CW0007007
  • 5,681
  • 4
  • 26
  • 31
5

This is more of an important comment, but I couldn't fit it in.

If you do

weak let name : SomeClass

It will give the following error:

'weak' must be a mutable variable, because it may change at runtime

You must do

weak var name : SomeClass

'weak' variable should have optional type 'SomeClass?'

So you must do:

weak var name : SomeClass?

Also, in Swift, all weak references are non-constant Optionals (think var vs. let) because the reference can and will be mutated to nil when there is no longer anything holding a strong reference to it. See here

As a result of this mandatory optional-ization, you always need to unwrap it so you can access its actual value.

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • @ChrisPrince generally not recommended to do implicitly unwrapped optionals, but yes you can do that as well... – mfaani Oct 10 '17 at 15:48
  • We can chose to disagree on this point. And also take a look at IBOutlet member variables in Swift. – Chris Prince Oct 10 '17 at 19:13
4

Just wanted you to know that a var is strong by default but by adding "weak" in front of it you make it weak. In case you missed it

nevva
  • 151
  • 2
  • 3
  • 12
1

Details

  • Xcode 11.3.1, Swift 5.1

More info about ARC usage

Full sample

import Foundation

class BasicClass: CustomStringConvertible {
    private var objectName: String
    init(objectName: String) { self.objectName = objectName; print ("INITED \(self)") }
    deinit { print ("DEINITED \(self)") }
    var description: String { return "\"\(objectName)\" of \"\(type(of: self))\", with \(referenceCountInfo)" }
    var referenceCountInfo: String { return "reference count to self: \(CFGetRetainCount(self))" }
}

class Class1: BasicClass {
    var objectWithStrongReference: Class2?
    override var description: String {
        return super.description + "\n -- nested obj with strong reference: \(objectWithStrongReference?.referenceCountInfo ?? "nil")"
    }
}

class Class2: BasicClass {
    weak var objectWithWeakReference: Class1?
    override var description: String {
        return super.description + "\n -- nested obj with weak reference: \(objectWithWeakReference?.referenceCountInfo ?? "nil")"
    }
}

var obj1: Class1? = Class1(objectName: "obj1")
var obj2: Class2? = Class2(objectName: "obj2")

print("\n=====================================")
print("obj1.value = obj2, obj2.value = obj1")
obj1?.objectWithStrongReference = obj2
obj2?.objectWithWeakReference = obj1
print(obj1 ?? "nil")
print(obj2 ?? "nil")
print("\n=====================================")
print("obj2 = nil")
obj2 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")

print("\n=====================================")
print("obj1 = nil")
obj1 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")

Logs

INITED "obj1" of "Class1", with reference count to self: 3
 -- nested obj with strong reference: nil
INITED "obj2" of "Class2", with reference count to self: 3
 -- nested obj with weak reference: nil

=====================================
obj1.value = obj2, obj2.value = obj1
"obj1" of "Class1", with reference count to self: 6
 -- nested obj with strong reference: reference count to self: 4
"obj2" of "Class2", with reference count to self: 7
 -- nested obj with weak reference: reference count to self: 3

=====================================
obj2 = nil
"obj1" of "Class1", with reference count to self: 6
 -- nested obj with strong reference: reference count to self: 3
nil

=====================================
obj1 = nil
DEINITED "obj1" of "Class1", with reference count to self: 3
 -- nested obj with strong reference: reference count to self: 3
DEINITED "obj2" of "Class2", with reference count to self: 3
 -- nested obj with weak reference: nil
nil
nil
Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127