Deklarowałem protokół Swift:
protocol Option {
var name: String { get }
}
Deklaruję wiele implementacji tego protokołu - niektóre klasy, niektóre wyliczenia.
Mam kontroler widoku z właściwością zadeklarowaną jako tak:
var options: [Option] = []
Kiedy próbuję ustawić tę właściwość na tablicę obiektów, które implementują Option
protokół w innym VC prepareForSegue
, pojawia się błąd wykonania:
fatal error: array cannot be bridged from Objective-C
Dlaczego to nie działa? Kompilator ma wszystkie potrzebne informacje i w ogóle nie rozumiem, co ma z tym wspólnego Objective-C - mój projekt zawiera tylko pliki Swift, a te tablice nie wchodzą ani nie wychodzą z żadnych metod ramowych, które by to powodowały wymagają mostkowania do nich NSArray
.
ios
swift
swift-protocols
Robert Atkins
źródło
źródło
@objc
do swojego protokołu? stackoverflow.com/a/28029568/377369Odpowiedzi:
Znalazłem rozwiązanie. To dość ... niezadowalające , ale działa. Gdzie ustawiam tablicę na kontrolerze widoku docelowego, robię:
destinationViewController.options = options.map({$0 as Option})
źródło
options as [Option]
Zostawiłeś tam bardzo odkrywczą uwagę, która sugeruje źródło problemu. „Tablica rzeczy, które implementują opcję” nie jest tablicą opcji.
Problem polega na tym, że typ
options
pleców w miejscu, w którym je tworzysz (w formacieprepareForSegue
). Nie pokazujesz tego kodu, ale założę się, że nie możesz go rzucić / wpisać w tym momencie. Dlatego zadanie kończy się niepowodzeniem.options
może być szereg rzeczy, które faktycznie zdarzają się w przypadku przyjęcia Option, ale to nie wystarczy; musi być wpisany jako tablica Option.Więc wróć
prepareForSegue
, utwórz swój plikoptions
następującą:let options : [Option] = // ... whatever ...
Teraz będziesz mógł przypisać go bezpośrednio do
destinationViewController.options
.Oto krótki przypadek testowy (na placu zabaw; nie znoszę placów zabaw, ale mogą mieć swoje zastosowania):
protocol Option { var name : String {get} } class ViewController : UIViewController { var options : [Option] = [] } enum Thing : Option { var name : String { get { return "hi" } } case Thing } let vc = ViewController() let options : [Option] = [Thing.Thing] vc.options = options // no problem
(Przetestowałem to również w rzeczywistej aplikacji z rzeczywistym
prepareForSegue
i działa dobrze).źródło
viewController.options = things as [Option]
), ani tworzenie zmiennej tymczasowej jawnie wpisanej, jak[Option]
sugerujesz tutaj, w rzeczywistości nie działa. W obu przypadkach pojawia się błąd wykonania.Miałem ten sam problem i naprawiłem go przy oznaczaniu mojego protokołu
@objc
, w twoim przypadku wyglądałoby to tak@objc protocol Option { var name: String { get } }
Mam rozwiązanie z tej odpowiedzi
źródło
Ten również działa dobrze
destinationViewController.options = options.map{$0}
źródło