Friday, 15 January 2010

multithreading - Threading issue with UICollectionview loading images from CloudKit -



multithreading - Threading issue with UICollectionview loading images from CloudKit -

i'm having threading issue loading images in collectionview info coming cloudkit. know threading/blocking issue because before implemented ck, dumped images in folder on desktop , read/parsed them there , had no issue. ck, created handful of records via dashboard , i'm getting expected records returned , utilize images results populate cv cells. store ck query results in array , utilize size of array set numberofitemsinsection delegate.

here's issue...in numberofitemsinsection delegate method, i'm calling model class, executes ck query. since network call, set in background thread. logging, can see query execute , results come - within 2-3 seconds. however, cv cells never display , don't see custom cell initialized (via logging). if tap photographic camera button , take photo, i've implemented, take resulting image , add together array, phone call reloaddata on cv , cells (and images) appear, including new image taken camera.

by accident, found out hack works, calling reloaddata on cv inside background thread of numberofitemsinsection delegate method. result, thought might have stumbled on solution switching main thread when calling reloaddata, set in sort of endless loop of continuously calling numberofitemsinsection method , cellforitematindexpath , made lagged point barely scroll , tapping on of cells wouldn't anything.

at point, after trying many, many various things, i'm @ finish loss on how prepare this. know pretty easy solution it's mutual load images asynchronously populate collectionview or tableview. can please provide guidance? in advance!!!

@property (nonatomic) nsinteger numberofitemsinsection; - (nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section { nslog(@"***numberofitemsinsection***"); dispatch_queue_t fetchq = dispatch_queue_create("load image data", null); dispatch_async(fetchq, ^{ self.numberofitemsinsection = [self.imageloadmanager.imagedataarray count]; [self.mycollectionview reloaddata]; // should done on main thread! }); nslog(@"numberofitemsinsection: %ld", (long)self.numberofitemsinsection); homecoming self.numberofitemsinsection; } - (uicollectionviewcell *)collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath { static nsstring *cellidentifier = @"cell"; // string value identifier cell reuse imageviewcell *cell = [collectionview dequeuereusablecellwithreuseidentifier:cellidentifier forindexpath:indexpath]; nslog(@"cellforitematindexpath: section:%ld row:%ld", (long)indexpath.section, (long)indexpath.row); cell.layer.borderwidth = 1.0; cell.layer.bordercolor = [uicolor graycolor].cgcolor; cell.imageview.contentmode = uiviewcontentmodescaleaspectfit; imagedata *imagedata = [self.imageloadmanager imagedataforcell:indexpath.row]; // maps model ui dispatch_async(dispatch_get_main_queue(), ^{ if (imagedata.imageurl.path) { cell.imageview.image = [uiimage imagewithcontentsoffile:imagedata.imageurl.path]; [cell setneedslayout]; } else { // if imageurl nil, image coming in photographic camera opposed cloud cell.imageview.image = imagedata.image; [cell setneedslayout]; } }); homecoming cell; }

before returning self.numberofitemsinsection should wait until async phone call finished. can using semaphores. why doing async? getting count of array. , shouldn't reloaddata there. start cloudkit query? doing onviewdidload? async operation. when completes doe reloaddata of collectionview. besides doing enough:

- (nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section { homecoming [self.imageloadmanager.imagedataarray count]; }

if want utilize async there, have wait result. alter code like:

- (nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section { nslog(@"***numberofitemsinsection***"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); dispatch_queue_t fetchq = dispatch_queue_create("load image data", null); dispatch_async(fetchq, ^{ self.numberofitemsinsection = [self.imageloadmanager.imagedataarray count]; [self.mycollectionview reloaddata]; // should done on main thread! dispatch_semaphore_signal(sema); }); nslog(@"numberofitemsinsection: %ld", (long)self.numberofitemsinsection); dispatch_semaphore_wait(sema, dispatch_time_forever); homecoming self.numberofitemsinsection; }

and why go main queue in cellforitematindexpath? it's executed on main queue.

multithreading ios8 uicollectionview cloudkit

No comments:

Post a Comment