Objective C : Class Instance vs Delegate (callbacks, completions)

I’m still learning and trying to understand the differences a bit.
I think I may have figured something out, but looking for some advice, tips or articles to read
about Delegate’s.

Thru my recent coding I had discovered “Shared Instances” and that was great as I was creating
separate instances of a Class and then when I updated the properties of the Class Instance from Class A, I was realizing that my Class B was not able to access those properties. It made sense that the instance would be different but I was trying to figure it out.

My current issue was running into Class C calling methods on an instance of Class D and
wanting to wait until that method completed (REST API GET call)
so that Class C could then continue working with the data from the the response
that the method in instance of Class D did.

My Class C would make the Post Call on the instance of Class D and then just
immediately start executing the next line in my script… and of course the
Post Call had not completed yet.

I was trying to use performSelectorOnMainThread:waitUntilDone: but that was not working.


// on Class C init , make instance of Class D (TMSpotRequest)
//  self.spotReqDel = [TMSpotRequest new];

-(void)postRequest {
    NSLog(@"TMSpotSearchReq postRequest B4 spotReqDel postListPageRequest");
    [self.spotReqDel performSelectorOnMainThread:@selector(postListPageRequest)
                                      withObject:nil
                                   waitUntilDone:true];
    NSLog(@"TMSpotSearchReq postRequest after spotReqDel postListPageRequest");
}

I read some info about retain cycles and self. I then made a new variable reference to the instance of Class D and made the property __weak. and then called the operation and that possibly seemed to help.


// on Class C init this get set Class D is TMSpotRequest
//  self.spotReqDel = [TMSpotRequest new];

-(void)postRequest {
    NSLog(@"TMSpotSearchReq postRequest B4 spotReqDel postListPageRequest");
     __weak TMSpotRequest *sptReqweakSelf = self.spotReqDel;
    [sptReqweakSelf performSelectorOnMainThread:@selector(postListPageRequest)
                                      withObject:nil
                                   waitUntilDone:true];
    NSLog(@"TMSpotSearchReq postRequest after spotReqDel postListPageRequest");
}

One question should I define in Class C my instance property of Class D as
(nonatomic, weak) ? will that help?


@property (nonatomic, weak) TMSpotRequest *spotReqDel;

Oh I just tried it a compiler warned about my init assignment:
self.spotReqDel = [TMSpotRequest new];
“Assigning retained object to weak property; object will be released after assignment”

After reading a bit more on delegates what I think I will do is implement some
delegate protocol methods in my Class D that would be like:


-(void)requestDidError:(NSError)*error;
-(void)requestDidFinishLoadingData:(BOOL)dataLoaded;
-(void)requestParseDidError:(NSError)*error;
-(void)requestDidParseData:(BOOL)dataDidParse;
// or this may even be better??
-(void)requestDidParseData:(id)parsedData;

then in my Class D once the request completed the tasks I would then call


(void)postFunction: ... {
[[SPTRequest sharedHandler] performRequest:request callback:^(NSError *error, NSURLResponse *response, NSData *data) {
        if (error != nil) {
           [ self.delegate requestDidError:&error];
            return;}
        
            NSError *parseErr = nil;
            SPTListPage *page = [SPTSearch searchResultsFromData:data withResponse:response queryType:aSearchQueryType error:&resperr];

             if (parseErr != nil) {
                 NSLog(@"TMSpotRequest postListPageRequest page error");
                 [ self.delegate requestParseDidError:&parseErr];
                 return;
             }
      
          NSLog(@"TMSpotRequest postListPageRequest a page is: %@", page);
          [self saveResultsPage:page];
           self.requestStatus = @"YES";
          [ self.delegate requestDidParseData:yes];
          // or this
          //    [ self.delegate requestDidParseData:page];
       
    }];
}

any advice, tips, guides?

thanks

You have a choice. A delegate is good, but can be complicated if more than one object uses the target object. You can also pass the sender as an argument, so it becomes a sort of one-time delegate. And you can use notifications instead. All have their pros and cons.