问题
so the story goes like this :)
i am trying to block enumerate objects in an NSArray and dynamically create UITableViews for each of them and add them in UIScrollView. i am using Lighter View Controllers from www.objc.io for the sake of readability and reusability. the dataSource gets created for each UITableView separately. the problem is i crash all the time with
-[NSObject(NSObject) doesNotRecognizeSelector:]
i found out from posts on stack that objects in block enumeration are weak retained for speed concerns and can confirm that the dataSource gets actually deallocated for each table.
i even tried to init ArrayDataSource with __strong but with no effect.
__strong ArrayDataSource *customdayTableDataSource = [[ArrayDataSource alloc] initWithConfigureCellBlock:configureCell cellIdentifier:DayTableCellIdentifier];
what am i doing wrong in the block? can you please point me the right direction?
TableViewCellConfigureBlock configureCell = ^(id cell, id object) {
[cell configureForObject:object];
};
[NSArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
int tableHorizontalPosition = [[UIScreen mainScreen] bounds].size.width * idx;
int tableHeight = [[UIScreen mainScreen] bounds].size.height;
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(tableHorizontalPosition, 0, [[UIScreen mainScreen] bounds].size.width, tableHeight) style:UITableViewStylePlain];
[table setDelegate:self];
ArrayDataSource *customDataSource = [[ArrayDataSource alloc] initWithConfigureCellBlock:configureCell cellIdentifier:MyCellIdentifier];
[customTableDataSource setOriginalData:[NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil]];
[table setDataSource:customTableDataSource];
[[self myUIScrollView] addSubview:table];
}];
as pointed out with rmaddy i added each dataSource to an NSArray initialized out of the scope of the block. this solved my problem. thank you
回答1:
As people said in comments, you must create your datasorces somewhere where they will be "alive" as long as the tableviews, or maybe easier solution would be to create strong reference using objc_setAssociatedObject
In your class declare some static char strongReferenceKey
and in your block, after setting datasource, do:
objc_setAssociatedObject(table, &strongReferenceKey, customDataSource, OBJC_ASSOCIATION_RETAIN);
That way table will have strong reference on the datasource, which will be released when table gets deallocated.
P.S. Make sure you import runtime.h:
#import <objc/runtime.h>
来源:https://stackoverflow.com/questions/36208884/creating-uitableviews-in-array-block-enumeration-causes-crash