target-c Как предотвратить действие во время выполнения потока - PullRequest
0 голосов
/ 21 марта 2012

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

У меня есть метод, который должен загружать данные для сервера и получать доступ к памяти в зависимости от данных,этот процесс занимает много времени, поэтому я выполняю его из вторичного потока следующим образом:

-(void)showPeople{
   dispatch_queue_t pintaOcupantes = dispatch_queue_create("Pinta Ocupantes", NULL);
   dispatch_async(pintaOcupantes, ^{
     //BUNCH OF CODE
     [self isPersonIn:jid];
     //MORE CODE that include methods calling isPersonIn

});

Внутри этого блока находится isPersonIn.Он вылетает, если я слишком быстро нажимаю кнопку, которая выполняет showPeople.IsPersonIn выглядит примерно так:

-(int)isPersonIn:(XMPPJID *)jid{
    int i = 0;
    for(NSDictionary *card in self.listaGente){
        NSLog(@"la jid es: %@", [card objectForKey:@"jid"]);
        NSLog(@"la jid del usuario es: %@", jid.user);
        if([[card objectForKey:@"jid"] isEqualToString:jid.user]){
           return i;
        }
        i++;
    }
    return -1;
}

Он сравнивает XMPPJID с массивом, который является переменной экземпляра.isPersonIn вызывается несколько раз из разных методов, но все методы, которые вызывают его, принадлежат блоку, так что, как я понимаю, все выполнения isPersonIn должны быть сериализованы, FIFO, верно?

Но если я нажму клавишуКнопка, которая выполняет showPeople, та, которая содержит блок, много раз очень быстро, приложение падает на isPersonIn, иногда без какого-либо сообщения.Я могу видеть потоки, когда он падает, и я вижу, по крайней мере, 2 потока с isPersonIn последними в стеке, что не имеет смысла, так как блок должен выполняться по одному, а не несколько потоков одновременно, верно?

Любая помощь будет очень сильно оценена.

Спасибо!

[EDIT] Кроме того, массив экземпляра self.listaGente изменяется вне блока.

Ответы [ 2 ]

1 голос
/ 21 марта 2012

Я не эксперт по GCD, но я подозреваю, что причиной получения нескольких потоков является то, что вы создаете новую очередь отправки каждый раз, когда вызывается showPeople.

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

[EDIT] Если коллекция модифицируется вне блока, но во время выполнения блока, это может бытьисточник вашего крушения.Из Документация по быстрому перечислению :

Перечисление является "безопасным" - перечислитель имеет защиту от мутаций, поэтому , если вы пытаетесь изменить коллекцию во время перечисления, является исключениемподнял .

0 голосов
/ 21 марта 2012

В этом случае защита массива, который провоцировал сбой моего приложения, устранила проблему.

с использованием:

@syncronized(theArray){
    //CODE THAT WILL ACCESS OR WRITE IN THE ARRAY
}

Таким образом потоки будут остановлены раньше, если поток уже существуетвыполнение этого кода, как мьютекс или семафор

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...