W moim TextViewTableViewCell
mam zmienną do śledzenia bloku i metodę konfiguracji, w której blok jest przekazywany i przypisywany.
Oto moja TextViewTableViewCell
klasa:
//
// TextViewTableViewCell.swift
//
import UIKit
class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {
@IBOutlet var textView : UITextView
var onTextViewEditClosure : ((text : String) -> Void)?
func configure(#text: String?, onTextEdit : ((text : String) -> Void)) {
onTextViewEditClosure = onTextEdit
textView.delegate = self
textView.text = text
}
// #pragma mark - Text View Delegate
func textViewDidEndEditing(textView: UITextView!) {
if onTextViewEditClosure {
onTextViewEditClosure!(text: textView.text)
}
}
}
Kiedy używam metody konfiguracji w mojej cellForRowAtIndexPath
metodzie, jak prawidłowo używać słabego Ja w bloku, który przekazuję.
Oto, co mam bez słabego Ja:
let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {(text: String) in
// THIS SELF NEEDS TO BE WEAK
self.body = text
})
cell = bodyCell
UPDATE : Do pracy przy użyciu [weak self]
:
let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {[weak self] (text: String) in
if let strongSelf = self {
strongSelf.body = text
}
})
cell = myCell
Kiedy robię to [unowned self]
zamiast [weak self]
i wyciągam if
oświadczenie, aplikacja ulega awarii. Jakieś pomysły, jak to powinno działać [unowned self]
?
ios
swift
retain-cycle
NatashaTheRobot
źródło
źródło
Odpowiedzi:
Jeśli jaźń może być zerowa w zamknięciu, użyj [słabe ja] .
Jeśli jaźń nigdy nie będzie zerowa w zamknięciu, użyj [nieposiadanego ja] .
Jeśli to się zawiesza, kiedy używasz [nieposiadanego ja] , przypuszczam, że w pewnym momencie tego zamknięcia jaźń jest zerowa, dlatego zamiast tego musiałeś iść z [słabym ja] .
Bardzo podobał mi się cały rozdział podręcznika dotyczący używania mocnych , słabych i nieposiadanych w zamknięciach:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
Uwaga: użyłem terminu zamknięcie zamiast bloku, który jest nowszym terminem Swift:
Różnica między blokiem (Cel C) a zamknięciem (Swift) w iOS
źródło
unowned
. Nie warto ryzykować awarii aplikacji.Umieść
[unowned self]
przed(text: String)...
zamknięciem. Nazywa się to listą przechwytywania i umieszcza instrukcje dotyczące własności na symbolach przechwyconych w zamknięciu.źródło
** EDYTOWANE dla Swift 4.2:
Jak skomentował @Koen, Swift 4.2 umożliwia:
PS: Ponieważ mam kilka pozytywnych głosów, chciałbym polecić lekturę o unikaniu zamknięć .
ZMIENIONO: Jak skomentował @ tim-vermeulen, Chris Lattner powiedział w piątek, 22 stycznia, 19:51:29 CST 2016, ta sztuczka nie powinna być używana na sobie, więc proszę jej nie używać. Sprawdź informacje o zamknięciach bez ucieczki i odpowiedź na listę przechwytywania z @gbk. **Dla tych, którzy używają [słabe ja] na liście przechwytywania, zauważ, że self może być zerowe, więc pierwszą rzeczą, którą robię, jest sprawdzenie tego za pomocą oświadczenia strażnika
Jeśli zastanawiasz się, czym są cudzysłowy,
self
to profesjonalna sztuczka polegająca na użyciu self w zamknięciu bez konieczności zmiany nazwy na to , słabySelf lub cokolwiek innego.źródło
self
(w odwrotnych znakach). Nazwij to czymś innym, na przykład nonOptionalSelf i wszystko będzie dobrze.{ [weak self] in guard let self = self else { return }
można używać bez odwrotnych znakówUżyj listy przechwytywania
dodatkowe wyjaśnienia
źródło
EDYCJA: odniesienie do zaktualizowanego rozwiązania firmy LightMan
Zobacz rozwiązanie LightMan . Do tej pory korzystałem z:
Lub:
Zwykle nie trzeba określać typu parametru, jeśli jest on wywnioskowany.
Możesz całkowicie pominąć parametr, jeśli go nie ma lub jeśli odnosisz się do niego jak
$0
w zamknięciu:Tylko dla kompletności; jeśli przekazujesz zamknięcie do funkcji, a parametr nie jest
@escaping
, nie potrzebujeszweak self
:źródło
Od Swifta 4,2 możemy:
źródło
strongSelf
wyraźnie wyjaśnia znaczenie zmiennych / efekt uboczny, co jest miłe, jeśli kod jest dłuższy. jednak doceniam twoją opinię, nie wiedziałem, że c ++ używa takich fraz.guard let self = self else { return }
do rozpakowania[weak self]
: github.com/apple/swift-evolution/blob/master/propiments/…Swift 4.2
https://github.com/apple/swift-evolution/blob/master/propiments/0079-upgrade-self-from-weak-to-strong.md
źródło
Możesz użyć [słabe ja] lub [nieposiadane własne] na liście przechwytywania przed parametrami bloku. Lista przechwytywania ma opcjonalną składnię.
[unowned self]
działa dobrze, ponieważ komórka nigdy nie będzie zerowa. W przeciwnym razie możesz użyć[weak self]
źródło
Jeśli masz awarię, niż prawdopodobnie potrzebujesz [słabe ja]
Domyślam się, że blok, który tworzysz, jest nadal w jakiś sposób podłączony.
Utwórz przygotowanieForReuse i spróbuj wyczyścić znajdujący się w nim blok onTextViewEditClosure.
Sprawdź, czy to zapobiega awarii. (To tylko przypuszczenie).
źródło
Zamknięcie i silne cykle referencyjne [Informacje]
Jak wiesz, zamknięcie Swifta może uchwycić instancję. Oznacza to, że możesz używać
self
wewnątrz zapięcia. Szczególnieescaping closure
[About] może utworzyćstrong reference cycle
który. Nawiasem mówiąc, musisz jawnie używać wself
środkuescaping closure
.Szybkie zamknięcie ma
Capture List
funkcję, która pozwala uniknąć takiej sytuacji i przerwać cykl odniesienia, ponieważ nie ma silnego odniesienia do przechwyconej instancji. Element Capture List jest parąweak
/unowned
i odniesieniem do klasy lub zmiennej.Na przykład
weak
- bardziej preferowane, używaj go, gdy jest to możliweunowned
- używaj go, gdy masz pewność, że czas życia właściciela instancji jest dłuższy niż zamknięcieźródło