等待在iOS中完成的方法

时间:2012-10-04 10:48:15

标签: objective-c ios multithreading

我在目标c中有两个类Controller和Connector。 Controller要求连接器建立与Web服务的连接以获取一些数据。连接本身是通过委托实现的。如果数据到达,此委托将获取方法调用。我将委托设置为连接器本身。 我的问题是我希望Controller在Connector上调用一个方法,这个方法会立即返回数据。这是没有授权的。 我尝试了多线程并在Controller中等待,但我只能找到一个方法的多线程:

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

单个方法的多线程不起作用,因为无法调用Connector中的委托方法,因为整个Connector类没有线程化。任何人都可以帮我解决这个问题吗?

编辑:我添加了我调用连接器方法的代码(这是来自控制器的代码):

_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

2 个答案:

答案 0 :(得分:3)

我认为你应该使用积木。

Connector.h创建completitionBlock属性

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

在connector.m中我不知道你是如何连接到webservice的,这个例子是针对NSURLDelegate的

如果完成确定

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

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

 }

NSMutableData * dataOK

中收到的数据
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [dataOK appendData:data];
}

如果失败

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

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

}

然后从Controller类中调用连接器

[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
       }
    }];

答案 1 :(得分:1)

首先,我建议您使用Grand Central Dispatch而不是NSThread方式。 GCD更加优化,更易于使用。

在你的情况下,我不知道你为什么要对连接器的方法进行同步调用,而你的方法正在进行异步工作,但我认为这是一个非常糟糕的主意。 特别是如果您的连接器正在连接到Web服务。

我建议您对连接器的方法进行异步调用,该方法与Web服务进行同步连接。那是非常简单的GCD

dispatch_async(myQueue, ^{

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

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