#objective-c #nsarray #nsdictionary #objective-c-blocks #nszombie
#objective-c #nsarray #nsdictionary #objective-c-блоки #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-адрес изображения из массива.
Каждый второй раз, когда я хочу получить доступ к _selectedIssue в методе fillIssueArrayMethodWithIssueId, в моем приложении происходит сбой (SIGSEGV)
В соответствии с длительным исследованием, _selectedUssue мгновенно становится объектом зомби, когда метод StartDownloadImages завершен. Однако в этом методе я никогда не перераспределял этот массив. Я только что прочитал значения в этом массиве. Я уверен, что массив становится объектом зомби в этом методе, поэтому проблема исправлена при удалении «__block» в цикле for.
Итак, вопрос, __block type как может повлиять на объект _selectedIssue arrays?
Я просто хочу знать, чего мне не хватает…
Кстати, меня пытались использовать в методе StartDownloadImages перед циклом for, у меня был создан временный массив, и этот временный массив только что инициировался с помощью _selectedIssue mutableCopy или просто copy . Однако я снова столкнулся с проблемой зомби.
Комментарии:
1. Ваш вопрос трудно понять. Вы говорите: «итак, проблема устранена при удалении __типа блока в цикле for», но я не вижу ничего
__block
в опубликованном вами коде.2. @newacct да, я использую arc.
3. @trojanfoe __block находится в операторе for()