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
Best way to performselectoronmainthread in objective c?
提问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 线程安全。