ios - ARC Async Block Best Practices -


my application sends lots of messages via http requests. wrote simple wrapper around http request has primary method fire off request , return nsdata result.

it looks this:

- (void)sendrequest:(nsurlrequest *)request {     [[[nsurlsession sharedsession] datataskwithrequest:request                                      completionhandler:^(nsdata *data,                                                          nsurlresponse *response,                                                          nserror *error) {                                          nslog(@"---->> request returned");                                           if (_delegate == nil)                                              return;                                           if (error == nil) {                                              // forward along                                              [_delegate requestreturnedresult:data withresponse:response];                                           }                                          else {                                              // error occurred                                              [_delegate requestreturnederror:error withresponse:response];                                          }                                      }] resume]; } 

this httprequesthelper object ivar of message abstraction object outboundmessage packages data , sends out.

i think have messagesender object takes data, creates outboundmessage object, , sends out.

this abstraction works nicely except think i'm bumping issue arc.

when calls [messagesender send:], alloc outboundmessage , send out.

what see via nslog outboundmessage cleaned (presumably when send exits, see httprequesthelper cleaned up. then see nslog in completion handler of datataskwithrequest.

this indicates me around request helper cleaned prior http request completing. can imagine, try bubble response via delegate, exc_bad_access.

i can think of creative ways prevent deallocation , prevent i'd know conceptually best practices handling pattern of firing off messages enveloping objects clean after request done.

thanks.

update each wrapper object using initwithdelegate:self style patterns , noticed delegates being saved this:

@property (nonatomic, assign) id<httprequesterdelegate> delegate; 

i changed them strong , seems correct i'm not sure if i'm leaking memory or if there's more optimal approach.

first of all, nsurlsessiondatatask object, created nsurlsession - datataskwithrequest:completionhandler: method, retains completionhandler block object. block object isn't released until block executed when data task finished.

next, blocks capture(retain) local variables automatically. following line in code

if (_delegate == nil) 

is same as

if (self.delegate == nil) 

if delegate property strong

@property (nonatomic, strong) id<httprequesterdelegate> delegate; 

then self retained block. in case, self httprequesthelper object. httprequesthelper object , delegate object live long data task finished. it's safe.

but delegate property assign

@property (nonatomic, assign) id<httprequesterdelegate> delegate; 

it same __unsafe_unretained. blocks doesn't retain __unsafe_unretained object @ all. self wasn't retained, released before data task finished.

added

in case, can use local variable retain delegate object. because completionhandler uses delegate object, not httprequesthelper object itself.

id<httprequesterdelegate> delegate = _delegate;  [[[nsurlsession sharedsession] datataskwithrequest:request                                  completionhandler:^(nsdata *data,                                                      nsurlresponse *response,                                                      nserror *error) {                                      nslog(@"---->> request returned");                                       /*                                       * use `delegate` instead of `_delegate`                                       */                                      if (delegate == nil)                                          return;                                       ... 

in case, attribute of delegate property strong or assign, doesn't matter @ all.


Comments

Popular posts from this blog

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -