将保留对象分配给不安全的属性

时间:2015-08-13 20:31:42

标签: ios objective-c

我正在制作自定义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。

2 个答案:

答案 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实例的强引用。