Best way to performselectoronmainthread in objective c?
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.
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];
[sel开发者_如何转开发f.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?
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!
//Thanks!
Well, you're already using dispatch_async
. Then you should just use
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.
Pass a collection, such as a dictionary of unarchived objects.
You can also use an NSInvocation
.
since you are passing instance variables, another option would be to pass self and make self thread safe.
精彩评论