NSOperationQueue错误:线程1:EXC_BAD_ACCESS(代码= 2,地址=为0x4)

问题描述:

我喜欢创造一个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

'ramQueue'的'init'可能不是必须的,但是当我看到一个时,我总是感觉好些。 :) –

一对夫妇的想法:

  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),请确保将它们与主队列同步。您可以通过将这些更新分发回主队列或采用某种锁定机制来实现这一点。

好的,我想感谢罗布,指着我走向正确的方向!

这里是我的权利代码:

所有我创建[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 

     }]; 

    }]; 
} 

感谢阿甘!