ios - What's the best way to ensure a UITableView reloads atomically? -
i'v got uitableview datasource updated @ random intervals in short period of time. more objects discovered, added tableview's data source , insert specific indexpath:
[self.tableview beginupdates]; [self.tableview insertrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationautomatic]; [self.tableview endupdates];
the data source located in manager class, , notification posted when changes.
- (void)addobjecttodatasource:(nsobject*)object { [self.datasource addobject:object]; [[nsnotificationcenter defaultcenter] postnotification:@"datasourceupdate" object:nil]; }
the viewcontroller updates tableview when receives notification.
- (void)handledatasourceupdate:(nsnotification*)notification { nsobject *object = notification.userinfo[@"object"]; nsindexpath *indexpath = [self indexpathforobject:object]; [self.tableview beginupdates]; [self.tableview insertrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationautomatic]; [self.tableview endupdates]; }
this works fine, noticed in cases, second object discovered first 1 calling endupdates, , exception claiming have 2 objects in data source when tableview expecting one.
i wondering if has figured out better way atomically insert rows tableview. thinking of putting @synchronized(self.tableview) block around update, i'd avoid if possible because expensive.
the method i've recommended create private queue synchronously posting batch updates onto main queue (where addrow
method inserts item data model @ given indexpath):
@interface mymodelclass () @property (strong, nonatomic) dispatch_queue_t mydispatchqueue; @end @implementation mymodelclass - (dispatch_queue_t)mydispatchqueue { if (_mydispatchqueue == nil) { _mydispatchqueue = dispatch_queue_create("mydispatchqueue", null); } return _mydispatchqueue; } - (void)addrow:(nsstring *)data atindexpath:(nsindexpath *)indexpath { dispatch_async(self.mydispatchqueue, ^{ dispatch_sync(dispatch_get_main_queue(), ^{ //update data model here [self.tableview beginupdates]; [self.tableview insertrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationautomatic]; [self.tableview endupdates]; }); }); }
by doing way, don't block other threads , block-based approach ensures table view's animation blocks (the ones throwing exceptions) executed in right order. there more detailed explanation in rapid row insertion uitableview causes nsinternalinconsistencyexception.
Comments
Post a Comment