2014-09-16 22 views
6

mogłem wystąpienia klasy z ciągu w przykładzie ObjC.For, jakie określono nową klasę DBCell przez instacji UITableViewCell i I instancji klasy z nazwą z tych kodów:Jak utworzyć instancję klasy i init z ciągu znaków w Swift?

DBCell *cell=[tableView dequeueReusableCellWithIdentifier:cellClassname]; 
    if (cell==nil) { 
     Class cellClass=NSClassFromString(cellClassname); 
     cell=[cellClass alloc]; 
     cell=[cell initWithStyle:cellStyle reuseIdentifier:cellClassname]; 
    } 

teraz muszę migrować kody Swift, I przedefiniowali klasę DBCell w Swift:

class DBCell: UITableViewCell { 
    var label:String? 
    var key:String? 
    var managedObject:NSManagedObject? 
    var delegate:AnyObject? 
    convenience override init(style: UITableViewCellStyle, reuseIdentifier: String!) { 
     self.init(style: style, reuseIdentifier: reuseIdentifier) 
     self.textLabel.font=UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1) 
     self.backgroundColor=UIColor.blackColor() 
     self.textLabel.backgroundColor=UIColor.blackColor() 
    } 
    } 

Ale jak mogę instancję klasy i wywołać odpowiednią funkcję startowy?

+0

Uważam, że twój problem jest spowodowany przez złą architekturę, głównie brak właściwie stosowanego polimorfizmu. Czy mógłbyś pokazać więcej swojego oryginalnego kodu obj-c? Jaka jest różnica między różnymi komórkami? – Sulthan

+0

@Sulthan To dość powszechny wzór kakao. Co rozumiesz przez "właściwie zastosowany polimorfizm" w tym przypadku? Chodzi o to, że nazwy komórek są przechowywane w serii scenariuszy, co jest dość wygodne i użyteczne. Pytanie brzmi, jak to zrobić, zachowując bezpieczeństwo typu Swift (i jest to uzasadnione pytanie). –

Odpowiedz

15

Swift jest bardziej statycznie napisany, co czyni go znacznie bezpieczniejszym w czasie pracy. Na przykład, jeśli którykolwiek z łańcuchów jest błędny, nastąpi awaria (lub w najlepszym przypadku cicho nic nie zrobisz, co może być gorsze niż awarie) i kompilator nie może go dla ciebie złapać.

OK, ale jak sobie z tym poradzić? Najlepszym sposobem, IMO, w Swift jest jawne i tworzenie mapowania.

let cellMapping = [ 
    "DBCell": DBCell.self, 
] 

if let cellClass = cellMapping[cellClassName] { 
    let cell = cellClass(style: cellStyle, reuseIdentifier: cellClassName) 
    // use cell 
} 

Teraz, kiedy byłaby i zmienić nazwę DBCell, ale przegap ciąg w serii ujęć, wszystko będzie po prostu zachować działa zgodnie z oczekiwaniami, zamiast upaść lub braku cicho jak to będzie w ObjC.

Swift jest również sprytny w zakresie tych mapowań. Typ cellMapping powyżej to [String: DBCell.Type], więc jeśli masz specjalne init dla DBCell, będzie on dostępny. Ale jeśli słowniku wyglądało:

let cellMapping = [ 
    "DBCell": DBCell.self, 
    "OtherCell": UITableViewCell.self 
] 

następnie typ jest [String: UITableViewCell.Type]. Swift automatycznie wylicza najbardziej specyficzną klasę, która obejmuje wszystkie wartości. Jeśli dodałeś typ do tej listy, która nie miała jakiejś metody, której używasz, Swift może ją złapać podczas kompilacji. A jeśli popełnił błąd i dodał coś, co nie jest nawet komórka widok tabeli:

let cellMapping = [ 
    "DBCell": DBCell.self, 
    "OtherCell": UITableViewCell.self, 
    "BadCell": UICollectionViewCell.self 
] 

następnie Swift dadzą Ci kompilacji ostrzeżenie że utworzeniu AnyObject. To naprawdę miłe w pisaniu bezpiecznego, ale elastycznego kodu, wszystko za cenę słownika.

+0

Dzięki, zadziałało! – user1190178

+0

Czy istnieje sposób tworzenia mapowania komórek, które sprawią, że będzie to działać z różnymi typami? –

+0

Nie rozumiem pytania. Powinieneś zadać nowe pytanie SO ze szczegółami twojego konkretnego problemu. –

Powiązane problemy