I have a UIViewController which contains this property:
@property (weak, nonatomic) IBOutlet UITableView *customerTableView;
In the UIViewController’s viewDidLoad method, I have the following:
- (void)viewDidLoad
{
[super viewDidLoad];
// ...
CustomerTableViewDataSource *dataSource = [[CustomerTableViewDataSource alloc]
init];
[dataSource setData:customersSource];
[customerTableView setDataSource:dataSource];
}
I receive this with NSZombies enabled:
*** -[CustomerTableViewDataSource numberOfSectionsInTableView:]: message sent to
deallocated instance 0x3e07a0
The deallocated instance address is the same as the data source.
Is there any reason why the data source isn’t ‘sticking’?
Using the simulator and Zombies, I see that the reference is being released in viewDidLoad, which I suppose is no surprise since I declared it in that method and it should fall out of scope, however I would think that calling setDatasource would increase the refct. Well, it apparently doesn’t.
Is there any way I can change this behavior?
Note: Everything works if I create an ivar and store the data source, but I feel like that clutters my class. Is this just life in the city?
From the documentation of
UITableView:This means that
customerTableViewexpects you to retain your data source object, which you did not do. Same goes forUITableView‘s delegate (in fact, for almost any delegate in cocoa, exceptCALayer‘s one). This design decision is made for a reason: the object that holds on toUITableViewvery often also serves as its delegate. Had the delegate been retained, the programmers would have to deal with retain cycles.Unfortunately, the consequence of that decision is the problem that you are having: now you need to retain the data source (and the delegate, if any), e.g. by setting up an ivar.