【发布时间】:2014-11-05 11:33:16
【问题描述】:
我正在努力保持我的视图控制器清洁,如本文objc.io Issue #1 Lighter View Controllers 中所述。我在 Objective-C 中测试了这个方法,效果很好。我有一个单独的类,它实现了UITableViewDataSource 方法。
#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
从 tableview 控制器,我所要做的就是实例化这个类的一个实例并将其设置为 tableview 的数据源,它可以完美地工作。
self.dataSource = [[TableDataSource alloc] initWithItems:@[@"One", @"Two", @"Three"] cellIdentifier:@"Cell"];
self.tableView.dataSource = self.dataSource;
现在我正在尝试在 Swift 中做同样的事情。首先这是我的代码。它几乎是上面 Objective-C 代码的翻译。
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
}
}
我这样称呼它。
let dataSource = TableDataSource(items: ["One", "Two", "Three"], cellIdentifier: "Cell")
tableView.dataSource = dataSource
但应用程序崩溃并出现以下错误。
-[NSConcreteNotification tableView:numberOfRowsInSection:]:无法识别的选择器发送到实例
我检查了TableDataSource 的init 方法,并且项目和单元格标识符可以正常通过。我必须声明 UITableViewDataSource 方法 public 并删除 override 关键字,否则会产生编译时错误。
我不知道这里出了什么问题。谁能帮帮我?
谢谢。
【问题讨论】:
-
你能在崩溃点显示堆栈跟踪吗?
-
您的数据源似乎没有被保留。您将参考存储在哪里?
-
@jlehr 这确实是问题所在。我没有存储它!我创建了一个属性
var dataSource: TableDataSource!并将其分配给 tableview 的dataSource属性,现在它可以工作了:) 谢谢。 -
发生这种情况是因为
UITableView(以及其他视图/控件)的delegate和dataSource属性在Swift 中被声明为unowned,因此您需要自己引用委托/数据源(如果不是视图控制器本身)。 -
@NateCook 当我检查
dataSource属性的类型但不知道它是什么时,我确实看到了unowned的东西。感谢您澄清这一点。
标签: ios objective-c uitableview swift datasource