7

我正在为 iPhone 编写一个客户端-服务器应用程序。我有一个关于线程的问题。当我从设备访问我的在线数据库时,我需要在单独的线程上执行此操作,以免冻结 UI/主线程。但是当响应我从数据库中获取的数据时,我在主线程上调用这个方法:performSelectorOnMainThread。问题是这只让我向方法(WithObject)发送一个参数/对象,有时我有更多的参数想要传递。另一件事是我必须通过这个对象。如果我让应用程序崩溃,我不能通过 nil。

这是我今天的代码.. 我担心我使用的方法和线程错误的方式。

- (IBAction)testServerAction:(id)sender {

    [self.imageView setHidden:YES];
    [self.activityView setHidden:NO];
    [self.activityView startAnimating];
    dispatch_queue_t testServer = dispatch_queue_create("Test-Server-Thread", NULL);
    dispatch_async(testServer, ^{

        if ([self.arrayWithServerConnections count] > 0)
        {
            NSString *messageToShow;
            if ([self testServerMethod])
            {
                messageToShow = @"Server is working!";
                [self performSelectorOnMainThread:@selector(showMessageBoxWithString:) withObject:messageToShow waitUntilDone:YES];
                [self performSelectorOnMainThread:@selector(threadedUIActivityRemover:) withObject:nil waitUntilDone:YES];
            }else
            {
                messageToShow = @"Server is NOT working!";
                [self performSelectorOnMainThread:@selector(showMessageBoxWithString:) withObject:messageToShow waitUntilDone:YES];
                [self performSelectorOnMainThread:@selector(threadedUIActivityRemover:) withObject:nil waitUntilDone:YES];
            }
        }

    });

    dispatch_release(testServer);
}

-(void)threadedUIActivityRemover:(NSString *)string
{
    [self.imageView setHidden:NO];
    [self.activityView setHidden:YES];
    [self.activityView stopAnimating];
}

这是这样做的好方法吗,除了 performSelectorOnMainThread 之外还有什么你可以指出的,效果更好吗?

如您所见,我在此示例中将 nil 传递给 NSString 参数,因为我必须传递一些东西,如果我没有 NSString 作为方法中的 arg,则应用程序在传递 nil 时崩溃 evan。这是为什么? .请让我更清楚一点!

//谢谢!

4

4 回答 4

10

好吧,您已经在使用dispatch_async. 那么你应该只使用

     dispatch_async(dispatch_get_main_queue(),^ { ... } );

从后台线程内部在主线程上执行操作。例如,

     if ([self testServerMethod])
        {
            dispatch_async(dispatch_get_main_queue(),^ {
               [self showMessageBoxWithString: @"Server is working!"];
               [self threadedUIActivityRemover:nil];
            } );
        }else ...

它对您调用的方法的参数数量没有任何限制。

于 2011-08-29T16:40:32.607 回答
2

传递一个集合,例如未归档对象的字典。

于 2011-08-29T16:41:22.087 回答
1

您也可以使用NSInvocation.

于 2011-08-29T16:43:59.950 回答
0

由于您正在传递实例变量,因此另一种选择是传递 self 并使 self 线程安全。

于 2011-08-29T16:46:52.273 回答