Лучший способ выполнить селектор по основной теме в задаче c? - PullRequest
7 голосов
/ 29 августа 2011

Я пишу клиент-серверное приложение для iPhone. И у меня есть вопрос о потоке. Когда я получаю доступ к своей онлайн-базе данных с устройства, мне нужно сделать это в отдельном потоке, чтобы не заморозить UI / основной поток. Но при ответе на данные, которые я извлек из базы данных, я вызываю этот метод в главном потоке: executeSelectorOnMainThread. Дело в том, что это позволяет мне отправлять только один аргумент / объект в метод (WithObject), иногда у меня есть больше аргументов, которые я хочу передать. и еще одна вещь об этом, что я должен передать этот один объект. Я не могу передать ноль, если я делаю приложение вылетает.

Это мой код сегодня ... и я беспокоюсь, что я использую методы и неправильно использую потоки.

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

Это хороший способ сделать это, есть ли что-нибудь, кроме executeSelectorOnMain. На это вы можете указать мне, что работает лучше?

Как вы можете видеть, я передаю nil аргументу NSString в этом примере, потому что я ДОЛЖЕН передать что-то, если у меня нет NSString как аргумента в методе, приложение вылетает evan при передаче nil .. это? .. пожалуйста, сделайте это немного яснее для меня!

// Спасибо!

Ответы [ 4 ]

10 голосов
/ 29 августа 2011

Ну, вы уже используете 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 ...

Нет ограничений на количество аргументов для методов, которые вы вызываете.

2 голосов
/ 29 августа 2011

Передайте коллекцию, например, словарь неархивированных объектов.

1 голос
/ 29 августа 2011

Вы также можете использовать NSInvocation.

0 голосов
/ 29 августа 2011

, так как вы передаете переменные экземпляра, другой вариант - передать self и сделать self потокобезопасным.

...