2014-09-16 8 views
6

Czy te bloki zawsze zawiodą w tych samych okolicznościach (kiedy zamknięcie jest wykonywane, ale ja został zwolniony)?Nie ma logicznego odpowiednika słaby! w Swift

{ [unowned self] in 
    //use self 
    self.number = self.number + 1 
} 

{ [weak self] in 
    //use self! 
    self!.number = self!.number + 1 
} 
+0

Czy masz na myśli masz awarię, podczas wykonywania tego kodu? – Sandeep

+0

Tak, jeśli self został zwolniony. Pytam, czy oba bloki zawsze zachowują się tak samo logicznie? –

Odpowiedz

4

pozostawiony odniesienia nie zachowuje wyraźne odniesienie do siebie, ale to sprawia, że ​​założenie, że obiekt zawsze ma jakąś wartość (nie jest zerowa) i jeśli, jak niektórzy dealokuje self podczas wykonywania bloku, powyższy kod awarie.

W przypadku słabych, jak w twoim przykładzie, słabe jest opcjonalnym typem wewnątrz bloku, więc może być również wartość lub może być zero. Twoim obowiązkiem jest sprawdzenie, czy wartość istnieje i metody połączeń na niej. Jak wyżej, jeśli używasz rozpakowującego operatora (!), Gdy self został zwolniony, to z pewnością ulega awarii. Tak więc, zarówno wersja kodu ulega awarii, jeśli zdarza się tak, że blok jest nadal wykonywany, a self jest dealokowane w międzyczasie.

Więc proponuję użyć słaby, by chronić takie awarie stosując opcjonalne kontrole,

{ [weak self] in 
    if let me = self { 
     me.number = me.number + 1 
    } 
} 
+0

"i jeśli, niektórzy, jak zwolni się własnie podczas wykonywania bloku" lub zanim blok wykona – newacct

1

Tak, to są równoważne. To jest punkt unowned - to tak jak weak, z tym że nie musisz radzić sobie z opcjonalnym i rozwijać go, ponieważ jego typem jest nieopakowany typ nieopakowany; to jest weak, który zawsze jest siłą rozpakowywany przy każdym pojawieniu się.

+0

chociaż "unowned" jest niebezpieczne - ulegnie awarii, jeśli 'self' zostanie zwolniony. –

+1

@AaronBrager: Nigdy więcej "niebezpieczny" niż wymuszanie rozpakowywania. Pytanie brzmi, czy są one takie same. Jeśli był "słaby", a obiekt jest zwolniony, wartość będzie równa "zero". Odwleka si ˛ e wymuszenie rozpakowania opcjonalnego o wartosci 'nil'. – newacct

1

Należy używać go tak jak to

{ [weak self] in 

    guard let weakSelf = self else { 
     return 
    } 

    weakSelf.number = weakSelf.number + 1 
} 

Dzięki @ komentarzu José „s, należy pamiętać, że chociaż poniższy kod działa w tej chwili, ale to jest uważane za błąd kompilatora i należy unikać https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html.

Można także rozpakować self takiego:

{ [weak self] in 

    guard let `self` = self else { 
     return 
    } 

    // Now you can use `self` safely 
    self.number = self.number + 1 
} 
+0

Jest to jednak błąd kompilatora i należy go unikać: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html –

+0

@ José dziękuję za wskazanie tego! Dodam notatkę do postu, aby wszyscy wiedzieli! –

Powiązane problemy