2013-09-25 4 views
0

Я хотел создать NSOperationQueue, то NSOperatioQueue должен обновить UILable я создал этот код:NSOperationQueue ошибка: Тема 1: EXC_BAD_ACCESS (код = 2, адрес = 0x4)

NSOperationQueue * ramQueue = [NSOperationQueue alloc]; 
    [ramQueue addOperationWithBlock:^{ 
     while (TRUE) { 

      //Creating String 

      NSOperationQueue *main = [NSOperationQueue mainQueue]; 
      [main addOperationWithBlock:^{ 

       //Refresh Label 

      }]; 

     } 

    }]; 

Но это не будет работать, метка не показывает новые строки. приведена ошибка: [ramQueue addOperationWithBlock:^{

Кто-нибудь знает, как это исправить?

+0

Просьба предоставить более подробную информацию о том, чего вы пытаетесь достичь. Что вы понимаете, обновив UILabel? Почему вы вложили 2 'addOperationWithBlock:' звонки? –

+0

Предположительно, чтобы вернуть работу в основную очередь обновлений UI. Меня больше беспокоит цикл 'while (TRUE) - похоже, что одна операция будет работать довольно долгое время, потенциально либо голодая в основной очереди времени работы, либо перегружая ее новыми блочными операциями (или обоими!). – Tim

+1

«init» для 'ramQueue' может и не понадобиться, но я всегда чувствую себя лучше, когда вижу его. :) –

ответ

0

Пара мыслей:

  1. Это [NSOperationQueue alloc] должно быть [[NSOperationQueue alloc] init].

  2. Я бы посоветовал никогда не кончать цикл while. Если вы хотите многократно делать что-то, повторяющийся таймер (с некоторой разумной скоростью, вероятно, не более 10-20 раз в секунду) может быть лучшей конструкцией. Если вы используете конструкцию цикла while, вы можете легко завершить операции проводки в основной очереди быстрее, чем основной цикл может их обработать. (Это зависит от того, что внутри этого while цикла.)

  3. Если вы остаетесь с этим while цикла (который, опять-таки, я бы отговорить вас от этого), вы, вероятно, хотите @autoreleasepool внутри есть поэтому любые авто выпустили объекты получить перераспределена.

    [ramQueue addOperationWithBlock:^{ 
        while (TRUE) { 
         @autoreleasepool { 
          //Creating String 
    
          NSOperationQueue *main = [NSOperationQueue mainQueue]; 
          [main addOperationWithBlock:^{ 
    
           //Refresh Label 
          }]; 
         } 
        } 
    }]; 
    

    Возможно, вы даже захотите использовать семафоры, чтобы гарантировать, что операция фона не выведет события слишком быстро.

  4. Возможно, вы не связаны с вашей проблемой, но если вы делаете что-либо, что обновляет общие ресурсы (например, меняет любые свойства класса или ivars), обязательно синхронизируйте их с основной очередью. Вы можете сделать это, отправив эти обновления обратно в основную очередь или используя механизм блокировки.

1

ОК, я хочу поблагодарить Роба за то, что он указал мне в правильном направлении!

вот мой правильный код:

Прежде всего я создал [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(updateRam) userInfo:nil repeats:YES]; вместо петли while(TRUE){}. Затем я исправил мой NSOperationQueue код вроде этого:

-(void)updateRam { 

    NSOperationQueue * ramQueue = [[NSOperationQueue alloc] init]; 
    [ramQueue addOperationWithBlock:^{ 

     //Create String 

     NSOperationQueue *main = [NSOperationQueue mainQueue]; 
     [main addOperationWithBlock:^{ 

     //Refresh Label 

     }]; 

    }]; 
} 

Спасибо Аган!

Смежные вопросы