1

我有一个UIViewController包含这个属性:

@property (weak, nonatomic) IBOutlet UITableView *customerTableView;

在 UIViewController 的viewDidLoad方法中,我有以下内容:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // ...
    CustomerTableViewDataSource *dataSource = [[CustomerTableViewDataSource alloc]
        init];
    [dataSource setData:customersSource];
    [customerTableView setDataSource:dataSource];
}

我在启用 NSZombies 的情况下收到此消息:

*** -[CustomerTableViewDataSource numberOfSectionsInTableView:]: message sent to 
deallocated instance 0x3e07a0

释放的实例地址与数据源相同。

数据源没有“粘住”有什么原因吗?

使用模拟器和 Zombies,我看到引用正在发布viewDidLoad,我认为这并不奇怪,因为我在该方法中声明它并且它应该超出范围,但是我认为调用setDatasource会增加 refct。好吧,它显然没有。

有什么办法可以改变这种行为吗?

注意:如果我创建一个 ivar 并存储数据源,一切正常,但我觉得这让我的课堂变得混乱。这只是城市里的生活吗?

4

2 回答 2

3

从以下文档UITableView

@property(nonatomic, assign) id 数据源

讨论

数据源必须采用 UITableViewDataSource 协议。不保留数据源。

这意味着customerTableView期望您保留数据源对象,而您没有这样做。' 的代表也是如此UITableView(事实上,对于可可中的几乎所有代表,除了CALayer' 代表)。做出这个设计决定是有原因的:UITableView经常持有的对象也充当其委托。如果委托被保留,程序员将不得不处理保留周期。

不幸的是,该决定的后果是您遇到的问题:现在您需要保留数据源(以及委托,如果有的话),例如通过设置 ivar。

于 2012-08-16T22:39:58.557 回答
0

甚至在 Apple 引入 ARC 之前,表视图的数据源和委托(几乎每个委托,按照设计)总是被声明为(分配)而不是(保留)。如今在 ARC 世界中,我确信它已被声明为 __weak (否则它会导致保留周期)。所以,是的,继续在你的课堂上制作一个 ivar - 这正是 ivar 的用途。

P.s.:创建单独的“数据源”和“委托”类通常是一个糟糕的设计——只要事情不变得复杂,最好使用视图控制器作为你的委托/数据源——在MVC,就是为它设计的层——(视图)控制器,它将逻辑链接到显示。

于 2012-08-16T22:28:26.597 回答