简体   繁体   中英

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

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.

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

您还可以使用NSInvocation

因为你传递实例变量,另一个选择是传递self并使自己的线程安全。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM