Решение проблемы EXC_BAD_ACCESS в какао? - PullRequest
1 голос
/ 07 октября 2011

Эй ... у меня есть следующий метод в какао ..

-(void)startUploadWithContainerName:(NSString *)containerName
{
//Make an object of NSFileManager and Fetch an array of local folder contents and cloud folder contents
NSFileManager *uploadManager=[[NSFileManager alloc] init];
NSString *uploadPath=[[[NSString alloc] initWithString:@"~/Cloud Briefcase"] stringByExpandingTildeInPath];
NSError *err;
NSArray *uploadFolderContents=[uploadManager contentsOfDirectoryAtPath:uploadPath error:&err];
ASICloudFilesObjectRequest *cloudList = [ASICloudFilesObjectRequest listRequestWithContainer:containerName];
[cloudList startSynchronous];
NSArray *cloudFolderContents = [cloudList objects];

[cloudList release];
[uploadManager release];

NSLog(@"%lu",[uploadFolderContents count]);
NSLog(@"\n%@\n\n%@",cloudFolderContents,uploadFolderContents);
NSString *notFoundPath;
NSString *foundPath;
NSString *foundCloudMatch;
NSDate *cloudUploadDate;

for (int j=1; j<[uploadFolderContents count]; j++) {
    int i=0;
    for (int k=0; k<[cloudFolderContents count]; k++) {
        if ([[[cloudFolderContents objectAtIndex:k] name] isEqualToString:[uploadFolderContents objectAtIndex:j]]) {
            i=1;
            foundPath=[uploadFolderContents objectAtIndex:j];
            foundCloudMatch=[cloudFolderContents objectAtIndex:k];
            cloudUploadDate=[[cloudFolderContents objectAtIndex:k] lastModified];
            break;
        }
        else{
            i=0;
            notFoundPath=[uploadFolderContents objectAtIndex:j];
            continue;
        }
    }

    if (i==1) {
        NSLog(@"Found In Cloud: %@",foundPath);
        NSString *uploadPath=[[NSString stringWithFormat:@"~/Cloud Briefcase/%@",foundPath] stringByExpandingTildeInPath];
        NSTimeZone *tCST=[NSTimeZone timeZoneWithAbbreviation:@"CST"];
        NSInteger cloudDifference=[tCST secondsFromGMTForDate:cloudUploadDate];

        NSFileManager *typeManager=[[NSFileManager alloc] init];
        NSError *Er;
        NSDictionary *propertiesOfUploadFile=[typeManager attributesOfItemAtPath:uploadPath error:&Er];

        NSDate *localUploadDate=[propertiesOfUploadFile objectForKey:NSFileModificationDate];

        NSInteger sourceUploadDifference=[[NSTimeZone systemTimeZone] secondsFromGMTForDate:localUploadDate];


        NSLog(@"Local Date %@",localUploadDate);
        NSLog(@"Local Difference %ld",sourceUploadDifference);
        NSTimeInterval diff=sourceUploadDifference-cloudDifference;
        NSTimeInterval sDiff=sourceUploadDifference;
        NSDate *lDate=[[NSDate alloc] initWithTimeInterval:sDiff sinceDate:localUploadDate];
        NSDate *comparisonDate=[[NSDate alloc] initWithTimeInterval:diff sinceDate:cloudUploadDate];
        NSLog(@"\nSDiff Value %@",lDate);
        NSLog(@"Comparison Date %@",comparisonDate);

        [localUploadDate release];
        [propertiesOfUploadFile release];
        [typeManager release];
        [tCST release];

        if ([comparisonDate compare:lDate]==NSOrderedAscending) {
            [comparisonDate release];
            [lDate release];
            NSLog(@"Got It");
            NSString *escString=[foundPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
            ASICloudFilesObjectRequest *request = 
            [ASICloudFilesObjectRequest putObjectRequestWithContainer:containerName objectPath:escString contentType:@"file" file:uploadPath metadata:nil etag:nil];
            [request startSynchronous];
            NSLog(@"Uploaded %@",foundPath);
        }



    }
    else{
        NSLog(@"Not Found In Cloud: %@",notFoundPath);
        NSString *uploadPath=[[NSString stringWithFormat:@"~/Cloud Briefcase/%@",notFoundPath] stringByExpandingTildeInPath];
        //          NSLog(@"%@",uploadPath);


        NSString *escString=[notFoundPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
        NSLog(@"URL ENCODED VALUE: %@",escString);

        ASICloudFilesObjectRequest *request = 
        [ASICloudFilesObjectRequest putObjectRequestWithContainer:containerName objectPath:escString contentType:@"file" file:uploadPath metadata:nil etag:nil];
        [request startSynchronous];
        NSLog(@"Upload Complete");
    }
}
[uploadPath release];

[cloudList release];
[uploadFolderContents release];

 }

Но он зависает, показывая исключение

Полученный сигнал EXC_BAD_ACCESS

Может кто-нибудь решить проблему?исключение происходит в NSLog (@ "Found In Cloud:% @", foundPath);

Ответы [ 4 ]

2 голосов
/ 07 октября 2011

Обычно для переменной среды NSZombieEnabled задается значение YES, а затем устраняется проблема. В вашем случае я вижу, что вы объявили указатели, не указывая на какой-либо объект, который опасен. Запуск вашего кода в Clang Analyzer выдаст предупреждение. Установите эти указатели на ноль. Вы объявили строковый указатель, но в вашем цикле for, если «if» не является истинным, тогда оно переходит в другое место, где foundPath никогда не указывает ни на что, и вы пытались получить к нему доступ в if (i == 1)

Обновление: Также рассмотрите ответ Лу Франко. Он тоже прав. Вы не являетесь владельцем объекта cloudList. Он автоматически выпущен, и вы перевыпускаете его, передавая сообщение об освобождении объекту cloudList [cloudList release]. В вашем случае это может не произойти сбой сразу, когда вы отпустите его, потому что контроль находится в том же цикле. Как только текущий пул автоматического выпуска потоков будет очищен, ваш код завершится с ошибкой EXC_BAD_ACCESS.

ASICloudFilesObjectRequest *cloudList = [ASICloudFilesObjectRequest listRequestWithContainer:containerName];
[cloudList startSynchronous];
NSArray *cloudFolderContents = [cloudList objects];
[cloudList release];// Remove this line 

Update2:

NSString *uploadPath=[[[NSString alloc] initWithString:@"~/Cloud Briefcase"] stringByExpandingTildeInPath];

Измените вышеприведенное на

NSString *uploadPath=[[NSString stringWithFormat:@"~/Cloud Briefcase"] stringByExpandingTildeInPath];

uploadPath в вышеприведенной строке по-прежнему указывает на автоматически выпущенный объект. Вы пропускаете созданную вами строку. Вызывать релиз неправильно. Так что удалите [uploadPath release], а также [cloudList release], вы выпускаете его снова и снова. И почему вы выпускаете явно автоматически выпущенный объект uploadFolderContents? удалите эти три строки из вашего кода:

[uploadPath release];

[cloudList release];
[uploadFolderContents release];

Обновление3: Исправлены проблемы с переизбытком. И updatePath в блоке if заменен на updatePathLocal, где существует конфликт с переменной updatePath с областью действия метода.

-(void)startUploadWithContainerName:(NSString *)containerName
{
//Make an object of NSFileManager and Fetch an array of local folder contents and cloud folder contents
NSFileManager *uploadManager=[[NSFileManager alloc] init];
NSString *uploadPath=[[NSString stringWithFormat:@"~/Cloud Briefcase"] stringByExpandingTildeInPath];
NSError *err = nil;
NSArray *uploadFolderContents=[uploadManager contentsOfDirectoryAtPath:uploadPath error:&err];
ASICloudFilesObjectRequest *cloudList = [ASICloudFilesObjectRequest listRequestWithContainer:containerName];
[cloudList startSynchronous];
NSArray *cloudFolderContents = [cloudList objects];

[uploadManager release];

NSLog(@"%lu",[uploadFolderContents count]);
NSLog(@"\n%@\n\n%@",cloudFolderContents,uploadFolderContents);
NSString *notFoundPath = nil;
NSString *foundPath = nil;
NSString *foundCloudMatch = nil;
NSDate *cloudUploadDate = nil;

for (int j=1; j<[uploadFolderContents count]; j++) {
    int i=0;
    for (int k=0; k<[cloudFolderContents count]; k++) {
        if ([[[cloudFolderContents objectAtIndex:k] name] isEqualToString:[uploadFolderContents objectAtIndex:j]]) {
            i=1;
            foundPath=[uploadFolderContents objectAtIndex:j];
            foundCloudMatch=[cloudFolderContents objectAtIndex:k];
            cloudUploadDate=[[cloudFolderContents objectAtIndex:k] lastModified];
            break;
        }
        else{
            i=0;
            notFoundPath=[uploadFolderContents objectAtIndex:j];
            continue;
        }
    }

    if (i==1) {
        NSLog(@"Found In Cloud: %@",foundPath);
        NSString *uploadPathLocal=[[NSString stringWithFormat:@"~/Cloud Briefcase/%@",foundPath] stringByExpandingTildeInPath];
        NSTimeZone *tCST=[NSTimeZone timeZoneWithAbbreviation:@"CST"];
        NSInteger cloudDifference=[tCST secondsFromGMTForDate:cloudUploadDate];

        NSFileManager *typeManager=[[NSFileManager alloc] init];
        NSError *Er = nil;
        NSDictionary *propertiesOfUploadFile=[typeManager attributesOfItemAtPath:uploadPathLocal error:&Er];

        NSDate *localUploadDate=[propertiesOfUploadFile objectForKey:NSFileModificationDate];

        NSInteger sourceUploadDifference=[[NSTimeZone systemTimeZone] secondsFromGMTForDate:localUploadDate];


        NSLog(@"Local Date %@",localUploadDate);
        NSLog(@"Local Difference %ld",sourceUploadDifference);
        NSTimeInterval diff=sourceUploadDifference-cloudDifference;
        NSTimeInterval sDiff=sourceUploadDifference;
        NSDate *lDate=[[NSDate alloc] initWithTimeInterval:sDiff sinceDate:localUploadDate];
        NSDate *comparisonDate=[[NSDate alloc] initWithTimeInterval:diff sinceDate:cloudUploadDate];
        NSLog(@"\nSDiff Value %@",lDate);
        NSLog(@"Comparison Date %@",comparisonDate);

        [typeManager release];

        if ([comparisonDate compare:lDate]==NSOrderedAscending) {
            [comparisonDate release];
            [lDate release];
            NSLog(@"Got It");
            NSString *escString=[foundPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
            ASICloudFilesObjectRequest *request = 
            [ASICloudFilesObjectRequest putObjectRequestWithContainer:containerName objectPath:escString contentType:@"file" file:uploadPath metadata:nil etag:nil];
            [request startSynchronous];
            NSLog(@"Uploaded %@",foundPath);
        }
    }
    else{
        NSLog(@"Not Found In Cloud: %@",notFoundPath);
        NSString *uploadPathLocal=[[NSString stringWithFormat:@"~/Cloud Briefcase/%@",notFoundPath] stringByExpandingTildeInPath];
        //          NSLog(@"%@",uploadPath);


        NSString *escString=[notFoundPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
        NSLog(@"URL ENCODED VALUE: %@",escString);

        ASICloudFilesObjectRequest *request = 
        [ASICloudFilesObjectRequest putObjectRequestWithContainer:containerName objectPath:escString contentType:@"file" file:uploadPathLocal metadata:nil etag:nil];
        [request startSynchronous];
        NSLog(@"Upload Complete");
    }
 }
}
1 голос
/ 07 октября 2011

Эта строка:

[cloudList release];

подозрительно, потому что вы не выделяли или не сохраняли cloudList - он, скорее всего, возвращается как авто-релиз, но прочитайте документы для ASICloudFilesObjectRequest.

Несмотря на это, я не думаю, что это ваша проблема - это вызовет проблемы позже, когда оно будет переиздано.

Я вижу много выпусков, которые кажутся плохими - потому что я не вижу соответствующих ассигнований или сохранений. Вам необходимо прочитать правила управления памятью для Objective-C (или перейти к автоматическому подсчету ссылок)

Я задокументировал методы отладки для EXC_BAD_ACCESS здесь:

http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

Легко попробовать:

  1. Запустить сборку и анализ (исправить все)
  2. Включите зомби
0 голосов
/ 07 октября 2011

это, вероятно, проблема с количеством ссылок.

для диагностики:

  • запустите статический анализатор
  • исправьте все проблемы статического анализатора
  • test

все еще возникают проблемы после исправления результатов статического анализатора?нет проблем:

  • в Инструментах, вы можете включить обнаружение зомби и историю распределения записей и подсчет ссылок.
  • запустить ваше приложение, выполнив шаги, необходимые для воспроизведения проблемы
  • Инструменты остановят выполнение, когда зомби будут обмениваться сообщениями.
  • , затем найдите распределение / объект, который был передан в сообщении, и пошагово просмотрите историю его существования / подсчета ссылок.

, что позволяет легко находить переизданные объекты (например, по часам внекоторые случаи до минут).

0 голосов
/ 07 октября 2011

Может быть, просто возможно "foundPath" не установлен в допустимое значение. Есть отладчик, возможно, вам стоит его использовать.

...