xcode 在目标c中执行selectoronmainthread的最佳方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7232959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 21:50:05  来源:igfitidea点击:

Best way to performselectoronmainthread in objective c?

objective-cmultithreadingxcodeperformselector

提问by Objective Coder

I'm writing a client-server app to iPhone. And I have a question about threading. When I access my online database from the device, I need to do this on a separate thread to not freeze the UI/main thread. But when responding to the data I've fetched from the database I call this method on the main thread: performSelectorOnMainThread. The thing is that this only lets me send one argument/object to the method (WithObject), sometimes I have more arguments I want to pass. and another thing about it is that I HAVE TO pass this one object. I can't pass nil, if I do the app crashes.

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

This is my code today.. and I'm worried that I'm using the methods and threading the wrong way.

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

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

Is this a good way of doing this, is there anything besides performSelectorOnMainThread this you can point me to, that works better?

这是一个很好的方法吗,除了 performSelectorOnMainThread 之外还有什么可以指点我的,效果更好吗?

As you can see I pass nil to an NSString argument in this example, because I HAVE to pass something, if I don't have NSString as an arg in the method, the app crashes evan when passing nil.. Why is this?.. please make this a bit clearer for me!

正如你所看到的,我在这个例子中将 nil 传递给了一个 NSString 参数,因为我必须传递一些东西,如果我在方法中没有将 NSString 作为参数,应用程序在传递 nil 时会崩溃 evan .. 为什么会这样?。 . 请让我清楚一点!

//Thanks!

//谢谢!

回答by Yuji

Well, you're already using dispatch_async. Then you should just use

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

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

from inside your background thread to perform things on the main thread. For example,

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

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

It doesn't have any constraint on the number of arguments for the methods you call.

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

回答by justin

Pass a collection, such as a dictionary of unarchived objects.

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

回答by justin

You can also use an NSInvocation.

您也可以使用NSInvocation.

回答by justin

since you are passing instance variables, another option would be to pass self and make self thread safe.

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