Próbuję zachować moje kontrolery widoku czyste zgodnie z opisem w tym artykule objc.io Issue #1 Lighter View Controllers. Przetestowałem tę metodę w Objective-C i działa dobrze. Mam oddzielną klasę, która implementuje metody UITableViewDataSource
.Oddzielanie źródła danych innej klasie w Swift
#import "TableDataSource.h"
@interface TableDataSource()
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, strong) NSString *cellIdentifier;
@end
@implementation TableDataSource
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier {
self = [super init];
if (self) {
self.items = items;
self.cellIdentifier = cellIdentifier;
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];
cell.textLabel.text = self.items[indexPath.row];
return cell;
}
@end
ze sterownika Tableview, wszystko co musisz zrobić, to instancję instancji tej klasy i ustawić ją jako źródło danych tableview i działa idealnie.
self.dataSource = [[TableDataSource alloc] initWithItems:@[@"One", @"Two", @"Three"] cellIdentifier:@"Cell"];
self.tableView.dataSource = self.dataSource;
Teraz próbuję zrobić to samo w Swift. Najpierw tutaj jest mój kod. Jest to prawie tłumaczenie kodu Objective-C powyżej.
import Foundation
import UIKit
public class TableDataSource: NSObject, UITableViewDataSource {
var items: [AnyObject]
var cellIdentifier: String
init(items: [AnyObject]!, cellIdentifier: String!) {
self.items = items
self.cellIdentifier = cellIdentifier
super.init()
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = items[indexPath.row] as? String
return cell
}
}
I tak to nazywam.
let dataSource = TableDataSource(items: ["One", "Two", "Three"], cellIdentifier: "Cell")
tableView.dataSource = dataSource
Ale aplikacja ulega awarii z następującym błędem.
- [NSConcreteNotification tableView: numberOfRowsInSection:]: nierozpoznany selektor wysyłane do instancji
I sprawdzone metody init
o TableDataSource
oraz przedmioty i identyfikator komórki jest przekazywana w porządku. Musiałem zadeklarować metody UITableViewDataSource
method public
i usunąć słowo kluczowe override
, w przeciwnym razie spowodowałoby to błędy czasu kompilacji.
Nie mam pojęcia, co się tutaj dzieje. Czy ktoś może mi pomóc?
Dziękuję.
Czy możesz pokazać ślad stosu w momencie awarii? –
Wygląda na to, że Twoje źródło danych nie zostało zachowane. Gdzie przechowujesz referencję? – jlehr
@jlehr To był rzeczywiście problem. Nie magazynowałem tego! Zrobiłem właściwość 'var dataSource: TableDataSource!' I przypisałem ją do właściwości 'dataSource' widoku tableview i działa teraz :) Dziękuję. – Isuru