2013-06-08 1 views
1

я обновляю мой TableView по результату загрузки JSon с сервера, используя NSOperationQueueMulptiple Alloc из NSOperationQueue разбивает мое приложение

Добавление очереди:

- (void)AddQueue 
{ 
    NSOperationQueue *queue = [NSOperationQueue new]; 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                      selector:@selector(loadDataWithOperation) 
                       object:nil]; 
    [queue addOperation:operation]; 
} 

Загрузка результата:

-(void)loadDataWithOperation{ 

    // Create array to hold dictionaries 
    myObject = [[NSMutableArray alloc] init]; 

    NSData *jsonData = [NSData dataWithContentsOfURL: 
         [NSURL URLWithString:@"http://www.test.com/json.php"]]; 

    if(jsonData != nil) 
    { 
     NSError *error = nil; 
     id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; 
     if (error == nil){ 

      // values in foreach loop 
      for (NSDictionary *dataDict in jsonObjects) { 
       strPhotoID = [dataDict objectForKey:@"id"]; 
       strName = [dataDict objectForKey:@"title"]; 
       strUrl = [dataDict objectForKey:@"url"]; 
       strThumb = [dataDict objectForKey:@"thumb"]; 
       strDay = [dataDict objectForKey:@"day"]; 
       strDate = [dataDict objectForKey:@"date"]; 
       strLikes = [dataDict objectForKey:@"likes"]; 
       strDeviceid = [dataDict objectForKey:@"deviceid"]; 
       strActive = [dataDict objectForKey:@"active"]; 

       dict = [NSDictionary dictionaryWithObjectsAndKeys: 
         strPhotoID, photoid, 
         strName, title, 
         strThumb, thumb, 
         strUrl, photourl, 
         strDay, day, 
         strDate, date, 
         strLikes, likes, 
         strDeviceid, deviceid, 
         strActive, active, 
         nil]; 


       [myObject addObject:dict]; 

       NSSortDescriptor * sortDesc = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO]; 
       [myObject sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]]; 


       [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 

       [self performSelectorOnMainThread:@selector(endAnimating) withObject:nil waitUntilDone:YES]; 


      } 
     } 

    } 


} 

Этот код работает ну и загрузите то, что мне нужно, но если я загружу свой результат, многократные сбои приложений. Я думаю, что это происходит из-за многих операций в одно и то же время. Как предотвратить сбой приложения?

Вход:

libobjc.A.dylib`_cache_getImp: 
0x39a39580: lsr.w r9, r1, #2 
0x39a39584: ldr r3, [r0, #8] // EXC_BAD_ACCESS 
0x39a39586: add.w r3, r3, #8 
0x39a3958a: ldr r12, [r3, #-8] 
0x39a3958e: and.w r9, r9, r12 
0x39a39592: ldr.w r0, [r3, r9, lsl #2] 
0x39a39596: teq.w r0, #0 
0x39a3959a: add.w r9, r9, #1 
0x39a3959e: beq 0x39a395b2    ; _cache_getImp + 50 
0x39a395a0: ldr.w r12, [r0] 
0x39a395a4: teq.w r1, r12 
0x39a395a8: bne 0x39a3958a    ; _cache_getImp + 10 
0x39a395aa: ldr.w r12, [r0, #8] 
0x39a395ae: mov r0, r12 
0x39a395b0: bx  lr 
0x39a395b2: mov.w r0, #0 
0x39a395b6: bx  lr 
0x39a395b8: nop  
0x39a395ba: nop  
0x39a395bc: nop  
0x39a395be: nop  

Стек след:

(
    0 testApp        0x000ddd09 -[Perjantai loadDataWithOperation] + 72 
    1 CoreFoundation      0x31d46ad4 <redacted> + 68 
    2 CoreFoundation      0x31c9e28f <redacted> + 290 
    3 Foundation       0x32647f65 <redacted> + 112 
    4 Foundation       0x325d1a89 <redacted> + 840 
    5 Foundation       0x32649fe7 <redacted> + 102 
    6 libdispatch.dylib     0x39e58793 <redacted> + 10 
    7 libdispatch.dylib     0x39e5c657 <redacted> + 278 
    8 libdispatch.dylib     0x39e5c7d9 <redacted> + 92 
    9 libsystem_c.dylib     0x39e807f1 <redacted> + 360 
    10 libsystem_c.dylib     0x39e80684 start_wqthread + 8 
) 
+0

Показать журнал сбоев и трассировки стека. – Wain

+0

Как часто вызывается метод AddQueue? Я вижу, что вы создаете новую операционную очередь для операции, а не просто создаете ОДНУ очередь в методе init класса и добавляете операцию в эту очередь. – 0x8badf00d

+0

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

ответ

2

В своем первом блоке кода, вы выделяете очереди, но не держать сильную ссылку на него, так что он получает сразу же перераспределяется. Создайте ivar, создайте одну очередь раньше и добавьте к ней объекты по мере необходимости. Используя ARC, ivar будет выпущен самостоятельно, но в вашем dealloc вы, вероятно, захотите либо дождаться завершения всех операций, либо отменить их, а затем ждать - чтобы избежать другого сбоя.

КОД:

@implementation myClass 
{ 
    NSOperation *q; 
} 

- (id)init.... 
... 
    q = [NSOperationQueue new]; 
... 
    return self; 
} 

- (void)dealloc 
{ 
    [q cancelAllOperations]; 
    [q waitUntilAllOperationsAreFinished]; 
    ... 
} 
+0

Можете ли вы привести мне пример? –