Resolving EXC_BAD_ACCESS Issue In Cocoa?

后端 未结 4 1156
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-23 15:00

Hey..i have the following method in cocoa..

-(void)startUploadWithContainerName:(NSString *)containerName
{
//Make an object of NSFileManager and Fetch an          


        
相关标签:
4条回答
  • 2021-01-23 15:23

    it's likely a reference count issue.

    to diagnose:

    • run the static analyzer
    • fix all static analyzer issues
    • test

    still having problems after fixing the static analyzer results? no problem:

    • in Instruments, you can enable zombie detection and record allocation history and reference counts.
    • run your app, performing steps required to repro the issue
    • Instruments will halt execution when a zombie is messaged.
    • then find the allocation/object that was messaged and step through its lifetime/ref count history.

    this makes locating over-released objects very easy to find (e.g. from hours in some cases to minutes).

    0 讨论(0)
  • 2021-01-23 15:36

    Maybe, just maybe "foundPath" is not set to a valid value. There's a debugger, maybe you should use it.

    0 讨论(0)
  • 2021-01-23 15:46

    This line:

    [cloudList release];
    

    is suspect because you didn't alloc or retain cloudList -- it is likely returned as autorelease, but read the docs for ASICloudFilesObjectRequest.

    Even so, I don't think that's your problem -- it would cause problems later once it was overreleased.

    I see a lot of releases that seem to be bad -- because I don't see corresponding allocs or retains. You need to read the rules of memory management for Objective-C (or move to automatic reference counting)

    I documented debugging techniques for EXC_BAD_ACCESS here:

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

    Easy things to try:

    1. Run Build and Analyze (fix everything)
    2. Turn on zombies
    0 讨论(0)
  • 2021-01-23 15:48

    Typically you would set the environment variable NSZombieEnabled to YES and then troubleshoot the issue. In your case I see that you have declared pointers without pointing to any object which is dangerous. Running your code in Clang Analyzer would report it as warning. Set those pointers to nil. You have declared string pointer but in your for loop if the "if" is not true then it goes to else where foundPath is never pointed to anything and you tried to access it in if(i==1)

    Update: Also consider Lou Franco 's answer. He is correct too. You don't own cloudList object. It is autoreleased and you are over-releasing it by passing release message to cloudList object [cloudList release]. In your case it might not crash instantly when you release it because control is in same loop. Once the current threads autorelease pool is drained your code will crash with 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];
    

    Change the above to

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

    uploadPath in above line still points to autoreleased object. You are leaking a string you have created. Calling release is wrong. So remove [uploadPath release] and also [cloudList release] you are releasing it again and again. And why are you releasing obviously autoreleased object uploadFolderContents ? remove these three lines from your code:

    [uploadPath release];
    
    [cloudList release];
    [uploadFolderContents release];
    

    Update3: Fixed over-release issues. And updatePath in if block changed to updatePathLocal where there is a conflict with updatePath variable with scope of method.

    -(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");
        }
     }
    }
    
    0 讨论(0)
提交回复
热议问题