Wzorzec delegacji (delegation) to jeden z kluczowych w ekosystemie Swift, szeroko stosowany do przekazywania odpowiedzialności za obsługę zdarzeń między obiektami. Delegacja pozwala klasie delegować część swojego zachowania innemu obiektowi (delegatowi), zazwyczaj określonemu za pomocą protokołu.
weak) odniesienie do obiektu delegata, aby uniknąć cyklu retain.protocol DataUpdateDelegate: AnyObject { func didUpdateData(_ data: String) } class DataProvider { weak var delegate: DataUpdateDelegate? func updateData() { // ... logika aktualizacji danych delegate?.didUpdateData("Nowe dane") } } class ViewController: UIViewController, DataUpdateDelegate { func didUpdateData(_ data: String) { print("Dane zostały zaktualizowane: \(data)") } }
weak (lub unowned), aby uniknąć cyklu retain.AnyObject, aby umożliwić użycie słabych odniesień.Jak zaimplementujesz delegację, jeśli twój delegat należy do typu wartości (np. struct)?
Odpowiedź:
W Swift delegaci muszą być typami referencyjnymi (class lub AnyObject), ponieważ dla słabego odniesienia dopuszczalny jest tylko typ referencyjny. Delegatem nie może być struct ani enum, w przeciwnym razie pojawią się problemy: kompilator nie pozwoli na użycie właściwości weak, a silne odniesienie spowoduje cykl retain.
// Błąd! Nie można zadeklarować delegata jako struct: kompilator nie pozwoli na zrobienie go weak protocol StructDelegate { ... } struct MyStructDelegate: StructDelegate { ... } weak var delegate: StructDelegate? // Błąd
Historia
W jednym z projektów zapomniano oznaczyć właściwość delegata jako weak. W rezultacie pomiędzy widokiem a delegatem powstał cykl retain, aplikacja zaczęła stopniowo "puchnąć" pod względem pamięci i padała po pół godzinie działania.
Historia
Delegat został zaimplementowany za pomocą typu wartości (struct), zamiast klasy. IBOutlet, który miał stać się delegatem, nie otrzymywał powiadomień — połączenie nie następowało w ogóle. Problem odkryto dopiero po analizie logów i debugu.
Historia
W projekcie protokół delegata nie dziedziczył po AnyObject, a właściwość delegata zadeklarowano jako weak var. Doprowadziło to do błędu kompilatora, który zespołowi zajęło dużo czasu, by zrozumieć i naprawić.