web-dev-qa-db-fra.com

Références fortes et faibles dans Swift

Dans l'objectif C, vous pouvez définir une propriété comme ayant une référence forte ou faible comme ceci:

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

Comment cela se fait-il rapidement?

45
67cherries

Directement à partir du 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") }
}

les propriétés sont fortes par défaut. Mais regardez la propriété du locataire de la classe "Appartement", elle est déclarée faible. Vous pouvez également utiliser le mot-clé sans propriétaire, qui se traduit par unsafe_unretained d'Objective-C

https://iTunes.Apple.com/tr/book/Swift-programming-language/id881256329?mt=11

63
Kaan Dedeoglu

Un var est fort par défaut. Vous pouvez ajouter le mot-clé faible avant une var pour le rendre faible.

12
Connor

Les propriétés sont fortes par défaut, mais si vous voulez une propriété faible, vous pouvez:

    weak var tenant: Person?

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

10
CW0007007

C'est plus un commentaire important, mais je ne pouvais pas l'adapter.

Si tu fais

weak let name : SomeClass

Cela donnera l'erreur suivante:

"faible" doit être une variable modifiable, car elle peut changer au moment de l'exécution

Tu dois faire

weak var name : SomeClass

La variable 'faible' devrait avoir le type facultatif 'SomeClass?'

Vous devez donc faire:

weak var name : SomeClass?

De plus, dans Swift, toutes les références faibles sont des options non constantes (pensez var vs let) car la référence peut et sera mutée à zéro quand il n'y a plus rien qui contient une référence forte. Voir ici

À la suite de cette option facultative-ization, vous devez toujours déballer afin que vous puissiez accéder à sa valeur réelle.

4
Honey

Je voulais juste que vous sachiez qu'un var est fort par défaut, mais en ajoutant "faible" devant lui, vous le rendez faible. Dans le cas où vous l'avez manqué

4
nevva

Détails

xCode 9.1, Swift 4

Plus d'informations sur l'utilisation de l'ARC

Échantillon complet

import UIKit

var str = "Hello, playground"

class BasicClass: CustomStringConvertible {
    let text: String
    init(text: String) { self.text = text }
    deinit { print ("Object of the \"\(className)\" class deinited") }

    var className: String {
        return "\(type(of: self))"
    }

    var referenceCount: Int {
        return CFGetRetainCount(self)
    }
    var description: String {
        return "className: \(className), reference count: \(referenceCount)"
    }
}

class Class1: BasicClass {
    var objectWithStrongReference: Class2?
    override var description: String {
        return super.description + ", embed strong obj reference count: \(objectWithStrongReference?.referenceCount ?? 0)"
    }
}

class Class2: BasicClass {
    weak var objectWithWeakReference: Class1?
    override var description: String {
        return super.description + ", embed weak obj reference count: \(objectWithWeakReference?.referenceCount ?? 0)"
    }
}

var obj1: Class1? = Class1(text: "String 1")
print(obj1 ?? "nil")
var obj2: Class2? = Class2(text: "String 2")
print(obj2 ?? "nil")

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

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

Résultat

enter image description here

0
Vasily Bodnarchuk