1

NSOperationQueue を使用してサーバーから json の結果をロードして、テーブルビューを更新します

キューの追加:

- (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 を作成し、早い段階で 1 つのキューを作成し、必要に応じてそれにオブジェクトを追加します。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 に答える