Задача c: Ошибка неправильного доступа при использовании PerformSelectorOnMainThread

Вот в чем проблема.

  1. У меня есть метод под названием -(void)searchInBackground, который работает в фоновом режиме (performSelectorInBackground).

  2. В этом методе у меня есть несколько разных потоков, которые также работают в фоновом режиме (performSelectorInBackground). Нравится:

    -(void)searchingInBackground
    {
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getDuplicatedPictures:) withObject:copyArray];
      }
    
      @autoreleasepool {
        [self performSelectorInBackground:@selector(getLocationsOfPhotos:) withObject:copyArray];
      }
    ... (and so on)
    }
    
  3. В каждой из функций в потоках (например, getDuplicatedPictures, getLocationsOfPhotos...) они будут генерировать NSStrings в конце, и я буду использовать эти строки для обновления моего графического интерфейса текстового поля.

  4. Чтобы обновить графический интерфейс моего текстового поля. Я создал функцию UpdateGUI, которая поможет мне обновить все мои NSStrings. Нравится,

    -(void)UpdateUI
    {
       [_NumDupPhotosLabel(label for GUI)  setStringValue: resultDupPhotos(string from thread function which is getDuplicatedPictures in this case)];
        ....(includes all of my strings from threads)
    }
    
  5. Вот проблема, когда я вызываю этот UpdateGUI, используя PerformSelectorOnMainThread в каждой из функций потоков. Это даст мне EXC_BAD_ACCESS. Вот что я сделал. Например:

    -(void)getDupicatedPictures
    {
         resultDupPhotos = .....;
         [self performSelectorOnMainThread:@selector(UpdateUI) withObject:nil waitUntilDone:YES];
    }
    
  6. Если я не использую PerformSelectorOnMainThread, просто устанавливаю значения непосредственно в этих функциях, все работает нормально. Я просто хочу лучше организовать код.

    -(void)getDuplicatedPictures
    {
         resultDupPhotos = .....;
         [_NumDupPhotosLabel  setStringValue: resultDupPhotos]; (works good and it will set the value to the GUI label)
    }
    

Ребята, подскажите, как это исправить? Спасибо!!!


person YU FENG    schedule 22.05.2013    source источник
comment
Вам нужно использовать потоки или вы могли бы использовать очереди и GCD?   -  person vikingosegundo    schedule 22.05.2013
comment
Возможно, здесь опечатка, но вы используете getDupicatedPictures вместо getDup(l)icatedPictures и UpdateUI вместо Update(G)UI.   -  person Vertig0    schedule 22.05.2013
comment
Если эти орфографические ошибки исправлены, как упомянул Патрисио, и ошибка все еще возникает, попробуйте включить NSZombies для ее отслеживания. stackoverflow.com/questions/5386160/   -  person rmooney    schedule 22.05.2013
comment
Кстати: методы не должны иметь префикс get, если только они не относятся к особому типу, а это не так. Кроме того, предоператоры и ивары должны начинаться со строчных букв. Имена методов всегда должны начинаться со строчной буквы.   -  person bbum    schedule 22.05.2013
comment
Спасибо за ваши предложения по именованию @bbum. :)   -  person YU FENG    schedule 22.05.2013


Ответы (1)


  • АРК или нет?

  • если у вас сбой, опубликуйте бэктрейс

  • окружение вызова performInBackground:... вызовом @autoreleasepool ничего не делает (NSAutoreleasePool тоже не поможет — вам нужно, чтобы пул автоматического освобождения был в потоке выполнения)

  • если переменная вызывает сбой, показать объявление и инициализацию переменной

  • одновременное создание группы потоков для выполнения большого количества работы, вероятно, будет медленнее, чем выполнение работы последовательно. Параллелизм всегда должен контролироваться. Если у вас есть длительная задача, вы можете запустить второй поток. Или вы можете изменить порядок операций. Проблема, однако, в том, что одновременный запуск нескольких потоков, особенно если эти потоки выполняют много операций ввода-вывода, только увеличит конкуренцию и, вероятно, может замедлить работу, часто намного медленнее.

Скорее всего, один из объектов, вычисленных в фоновом потоке, освобождается до того, как основной поток попытается его использовать. Как вы гарантируете, что resultDupPhotos действителен между потоками?

person bbum    schedule 22.05.2013
comment
Спасибо. Я сохраняю только один поток PerformInBackground и избавляюсь от других. Но я слышал, что если одна функция работает более 5 секунд или около того, мы предполагаем открыть новый поток, не так ли? Также, если @autoreleasepool ничего не делает. Что я должен делать? Должен ли я создать NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; вместо этого в функции? - person YU FENG; 22.05.2013