Friday, 15 February 2013

objective c - iOS: Why do I need to use sleep(1) after NSURLConnection sendAsynchronousRequest? -



objective c - iOS: Why do I need to use sleep(1) after NSURLConnection sendAsynchronousRequest? -

i want display image on screen take internet. have used nsurlconnection create asynchronous phone call take info and, in response block, called code assign uiimage object.

my question why need phone call sleep(1) after block execution? if i'm not calling it, image not drawn on screen. another, more elegant way achive this?

-(void)loadimage:(nsstring *)url { nsurl *imageurl = [nsurl urlwithstring:url]; nsoperationqueue *queue = [[nsoperationqueue alloc]init]; nsurlrequest *imagerequest = [nsurlrequest requestwithurl:imageurl cachepolicy:nsurlrequestreloadignoringlocalandremotecachedata timeoutinterval:5.0f]; [nsurlconnection sendasynchronousrequest:imagerequest queue:queue completionhandler:^(nsurlresponse *response, nsdata *data, nserror *connectionerror) { if(!connectionerror) { if(data) { //there goes main thingy self.myview.wallpaperimage = [uiimage imagewithdata:data]; [self.myview setneedsdisplay]; } else { nslog(@"no info found @ url:%@",url); } } else { nslog(@"could not connect %@",url); } }]; sleep(1); }

this:

self.myview.wallpaperimage = [uiimage imagewithdata:data]; [self.myview setneedsdisplay];

is happening on thread managed nsoperationqueue passed sendasynchronousrequest. methods need called main thread. sleep may causing main thread's runloop iterate, after calls appear have worked. prepare this, , avoid whole bunch of other problems current approach have, this:

[nsurlconnection sendasynchronousrequest:imagerequest queue:queue completionhandler:^(nsurlresponse *response, nsdata *data, nserror *connectionerror) { if([data length] > 0) { //there goes main thingy [[nsoperationqueue mainqueue] addoperationwithblock:^{ self.myview.wallpaperimage = [uiimage imagewithdata:data]; [self.myview setneedsdisplay]; }]; } else { // perform error handling here. } }];

this utilize [nsoperationqueue mainqueue] perform uikit calls main queue - not libdispatch. libdispatch low level interface, recommended best practice prefer higher level interface - in case, nsoperationqueue. uikit safe when called main thread (or queue). changes error handling behavior follow best practices platform - check result of phone call (in case, data) , process error returned.

your code illustration of why blocks retain captured objects (in case self). if there no retain cycle here, arc destroy queue goes out of scope, , block never execute. instead, because of retain cycle, queue stays around until block has executed.

ios objective-c uiimage nsurlconnection setneedsdisplay

No comments:

Post a Comment