tester
tester

Reputation: 3987

Waiting for methods to finish in iOS

I have two classes Controller and Connector in objective c. The Controller asks the Connector to build up a connection to a webservice to get some data. The connection itself is implemented with a delegate. This delegate gets a method call if the data arrived. I set the delegate to be the Connector itself. My problem is that I want the Controller to call a method on the Connector and this method immediately returns the data. This is without delegation. I tried out Multithreading and waiting in the Controller, but I only could find multithreading for a single method:

[NSThread detachNewThreadSelector:@selector(myMethod) toTarget:myClass withObject:nil];

Multithreading for a single method does not work, because the delegate method in the Connector can't be called, because the whole Connector class is not threaded. Can anyone help me how to solve this?

EDIT: I add the code where I call the connector method (this is code from the controller):

_data = nil;
dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
dispatch_async(myQueue, ^{
    _data = [_soapConnector startRequestWithSOAPMessage:soapMessage];
});

while(!_data){
    NSLog(@"waiting");
}
//data arrived successfully here so we can manipulate it

Upvotes: 1

Views: 6269

Answers (2)

iSofTom
iSofTom

Reputation: 1718

First, I recommend you to use Grand Central Dispatch instead of the NSThread way. GCD is more optimized, and more easy to use.

In your case, i don't know why you want to do a synchronous call of your connector's method whereas your method is doing an asynchronous job, but i think it's a very bad idea. Especially if your connector is doing a connection to a webservice.

I recommend you instead to make a asynchronous call of your connector's method which it is doing a synchronous connection to your webservice. That's very simple whith GCD

dispatch_async(myQueue, ^{

    NSData* data = [NSURLConnection sendSynchronousRequest:myRequest returningResponse:&response error:&error];

    dispatch_async(dispatch_get_main_queue(), ^{
        //update your UI
    });
});

Upvotes: 1

jcesarmobile
jcesarmobile

Reputation: 53301

I think you should use blocks.

In your Connector.h create a completitionBlock property

@property (nonatomic,copy)void (^completitionBlock) (id obj, NSError * err);

In the connector.m I don't know how do you connect to the webservice, this example is for NSURLDelegate

if finish ok

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

        if([self completitionBlock])
            [self completitionBlock](dataOK,nil);

 }

NSMutableData * dataOK is the data received in

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [dataOK appendData:data];
}

if fails

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

    if([self completitionBlock]) 
        [self completitionBlock](nil,error);   

}

And then from the Controller class you call the connector

[Connector getWebservice:^(id obj, NSError *err) {
        if (!err) {

            //Code executed when the webservice finish OK, obj will be the dataOK


        } else {

            //Code executed when the webservice return error
       }
    }];

Upvotes: 3

Related Questions