nsmutablearray中奇怪的NSZombie错误

时间:2014-06-16 08:35:31

标签: objective-c nsarray nsdictionary objective-c-blocks nszombie

几天前我遇到了一个奇怪的错误。幸运的是,我在4-5天内解决了这个错误。但是,我只是想知道错误发生的原因。

首先,我将用相同的代码示例描述情况。

@interface SampleViewController ()

@property (nonatomic, strong) NSMutableArray *selectedIssue;
@property (nonatomic, strong) NSOperationQueue *queueJSON;
@property (nonatomic, strong) NSOperationQueue *queueImage;

@end

@implementation SampleViewController

/** blah blah blah*/

- (void) fillIssueArrayMethodWithIssueId:(NSInteger) selectedId {

    NSString *requestURL = [NSString stringWithFormat:@"%@Issues/Get/?id=%d", kAPIRootURL, selectedId];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestURL] 
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData 
                                                       timeoutInterval:kNetworkTimeOut];

    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    op.responseSerializer = [AFJSONResponseSerializer serializer];

    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id response) {
        NSData *JSONData = [NSData dataWithContentsOfFile:filePath
                                                  options:NSDataReadingMappedIfSafe 
                                                    error:nil];
        NSMutableArray *responseObject = [NSJSONSerialization JSONObjectWithData:JSONData 
                                                                         options:NSJSONReadingMutableContainers 
                                                                           error:nil];

        if(responseObject) {
            if([responseObject isKindOfClass:[NSArray class]]) {
                _selectedIssue = [NSMutableArray arrayWithArray:responseObject];
            }
        }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];

    [_queueJSON addOperation:op];
}

-(void)startDownloadImages {

    NSArray *objPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *strPath = [objPaths lastObject];

    if(!_queueImage)
        _queueImage = [[NSOperationQueue alloc] init];

    _queueImage.maxConcurrentOperationCount = 3;

    NSBlockOperation *completionOperation = [NSBlockOperation new];

    for (__block NSDictionary *object in _selectedIssue) {
            // Photos
            NSString *imgURL = object[@"ImageUrl"];
            NSString *strImageFile = [NSString stringWithFormat:@"%@_%@", object[@"Id"], [imgURL lastPathComponent]];
            __block NSString *strImagePath = [NSString stringWithFormat:@"%@/Images/Issues/%@", strPath, strImageFile];

            NSURLRequest *request4Images = [NSURLRequest requestWithURL:[NSURL URLWithString:imgURL]];

            AFHTTPRequestOperation *operation4Images = [[AFHTTPRequestOperation alloc] initWithRequest:request4Images];

            [operation4Images setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id rawResult) {

                 BOOL isImageWrited = [rawResult writeToFile:strImagePath options:NSDataWritingAtomic error:nil];

                 if(isImageWrited) {
                     NSLog(@"Image Write Success : %@", operation.request.URL);
                 } else {
                    NSLog(@"Image Write Error: %@", imageWriteError.description);
                 }

            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                NSLog(@"Image Write Failed : %@ : %ld", operation.request.URL, (long)operation.response.statusCode);
            }];

            [completionOperation addDependency:operation4Images];
    }

    [_queueImage addOperations:completionOperation.dependencies waitUntilFinished:NO];
    [_queueImage addOperation:completionOperation];
}

@end

这是问题;

在应用程序生命周期中, fillIssueArrayMethodWithIssueId 方法首先将JSON数据提供给mutuablearray。然后通过从阵列中获取图像URL开始下载图像。

每隔一次,我想访问 fillIssueArrayMethodWithIssueId 方法中的 _selectedIssue ,我的应用程序崩溃(SIGSEGV)

根据长期调查,当 StartDownloadImages 方法完成时, _selectedUssue 会立即成为僵尸对象。但是在这个方法中我从来没有重新分配这个数组。我刚读过这个数组中的值。我确信该方法中的数组成为僵尸对象,因此在for循环中删除“__ block”时问题已解决。

所以问题, __ block 类型如何影响 _selectedIssue 数组对象?

我只是想知道我错过了什么......

顺便说一下,我在for循环之前尝试过 StartDownloadImages 方法,我创建了临时数组,这个临时数组刚刚用 _selectedIssue mutableCopy启动,或者只是复制。但是,我再次遇到了僵尸问题。

0 个答案:

没有答案