1

我通过使用 NSOperationQueue 从服务器加载 json 结果来更新我的 tableview

添加队列:

- (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
)
4

1 回答 1

3

在您的第一个代码块中,您分配了队列,但不保留对它的强引用,因此它会立即重新分配。创建一个 ivar,尽早创建一个队列,并根据需要向其中添加对象。使用 ARC,ivar 将自行释放,但在您的 dealloc 中,您可能希望等待所有操作完成,或者取消它们然后等待 - 以避免发生不同的崩溃。

代码:

@implementation myClass
{
  NSOperation *q;
}

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

- (void)dealloc
{
  [q cancelAllOperations];
  [q waitUntilAllOperationsAreFinished];
  ...
}
于 2013-06-08T13:26:59.403 回答