我正在制作自定义UITableViewDataSource
,当我将该数据源分配给TableView时,我收到以下错误:
"将保留的对象分配给不安全的财产;对象将在分配后发布"
以下是导致 ERROR :
的代码 self.tableView.dataSource = [[ShoppingListDataSource alloc] initWithItems:_shoppingLists identifier:@"ShoppingListTableViewCell" configureCellBlock:^(ShoppingListTableViewCell *cell, ShoppingList *shoppingList) {
[cell configure:shoppingList];
}];
ShoppingListDataSource.h:
@import UIKit;
typedef void (^ConfigureCellBlock) (ShoppingListTableViewCell *cell, ShoppingList *shoppingList);
@interface ShoppingListDataSource : NSObject<UITableViewDataSource>
-(instancetype) initWithItems:(NSArray *) items identifier:(NSString *) identifier configureCellBlock:(ConfigureCellBlock) configureCellBlock;
@property (nonatomic,strong) NSArray *items;
@property (nonatomic,copy) NSString *identifier;
@property (nonatomic,copy) ConfigureCellBlock configureCellBlock;
@end
ShoppingListDataSource.m:
-(instancetype) initWithItems:(NSArray *)items identifier:(NSString *)identifier configureCellBlock:(ConfigureCellBlock)configureCellBlock
{
self = [super init];
self.identifier = identifier;
self.items = items;
self.configureCellBlock = configureCellBlock;
return self;
}
我的视图控制器继承自UITableViewController。
答案 0 :(得分:4)
表视图不保留其数据源。他们只持有弱参考。当你这样做时:
self.tableView.dataSource = [[ShoppingListDataSource alloc] initWithItems:...
对这个新创建的对象的唯一引用是dataSource
。这意味着当你点击分号时,对象将被释放,dataSource
将被设置为nil。
您需要将此数据源存储在strong
属性中,可能位于控制器中。
(正如rmaddy指出的那样,我正在看iOS 9文档;在早期版本中,它是assign
,这更糟糕,但是基本问题相同。)
答案 1 :(得分:3)
在iOS 8.4及更早版本中,UITableView dataSource
(和delegate
)被定义为assign
属性(从iOS 9开始,它们是weak
)。
问题是您alloc/init
一个对象并将其设置为此assign
属性。
在块结束时,ShoppingListDataSource
将被释放,然后取消分配,因为没有更强的引用。所以现在表视图的dataSource
指向垃圾。这是错误消息的原因。
解决方案是在ivar或某处保留对ShoppingListDataSource
实例的强引用。