Reputation: 3987
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
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
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