2011-10-07 35 views
1

Hey..i在可可下面的方法..解決可可中的EXC_BAD_ACCESS問題?

-(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)發生異常;

回答

2

通常,您可以將環境變量NSZombieEnabled設置爲YES,然後解決問題。 在你的情況,我看到你已經聲明指針而不指向任何危險的對象。在Clang Analyzer中運行您的代碼會將其報告爲警告。 將這些指針設置爲nil。您已聲明的字符串指針,但你如果「如果」是不正確的,然後它去到別的for循環,其中foundPath是從來沒有指出任何東西,你試圖訪問它,如果(我== 1)

更新: 也考慮婁佛朗哥的答案。他也是對的。您不擁有cloudList對象。它是自動發佈的,並且通過將發佈消息傳遞給cloudList對象[cloudList發佈]來過度釋放它。 在你的情況下,它可能不會立即崩潰當你釋放它,因爲控制在同一個循環。一旦當前的線程自動釋放池被耗盡,你的代碼將崩潰並伴隨着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發佈]和[cloudList發佈],一次又一次地發佈它。爲什麼你會發布明顯自動發佈的對象uploadFolderContents?從代碼中刪除以下三行:

[uploadPath release]; 

[cloudList release]; 
[uploadFolderContents release]; 

UPDATE3:修正過放的問題。如果block中的updatePath更改爲updatePathLocal,其中up​​datePath變量與方法範圍發生衝突。

-(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

它解決了例外在於method..but它導致相同的異常在main.m文件 #進口<可可/ Cocoa.h> INT主(INT的argc,字符* argv的[]){ return NSApplicationMain(argc,(const char **)argv); } 返回NSApplica .....線似乎已經捕捉到的異常.. – proctr

+0

@twistedcerebrum考慮重構你的代碼,請。方法的本地變量與變量本地的相同名稱與if塊或塊的名稱相同。使我們難以閱讀您的代碼。你的應用崩潰了什麼? EXC_BAD_ACCESS?當你在調試模式下運行斷點時,它會顯示控制停在main方法中,它的正常並不意味着你需要修復main方法。它的原因是你搗毀了堆棧,所以它找不到當前函數的框架,或者它實際上停在另一個線程中。 – 0x8badf00d

+0

好man..made sense..thnx .. – proctr

1

這條線:

[cloudList release]; 

是犯罪嫌疑人,因爲你沒有頁頭或保留cloudList - 它很可能返回自動釋放,但閱讀ASICloudFilesObjectRequest的文檔。

即便如此,我不認爲這是你的問題 - 一旦它被過度發售,它會導致問題。

我看到很多版本似乎不好 - 因爲我沒有看到相應的分配或保留。你需要讀取內存管理的Objective-C的規則(或移動到自動引用計數)

我記錄的調試技術EXC_BAD_ACCESS這裏:

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

容易的事情嘗試:

  1. 運行的建立與分析(解決所有問題)
  2. 打開殭屍
0

也許,只是可能「foundPath」未設置爲有效值。有一個調試器,也許你應該使用它。

+0

沒有找到路徑設置爲一個有效的value..it已經驗證earlier..nd除了,,,當我評論該行...同樣的錯誤轉移到下一行.. – proctr

+0

呃!下一行也引用「foundPath」。 PYHOOYA! –

+0

是的..但foundPath驗證.. – proctr

0

這可能是引用計數問題。

診斷:

  • 運行靜態分析
  • 修復所有靜態分析儀固定靜態分析結果後發出
  • 測試

仍然有問題?沒問題:

  • 在Instruments中,您可以啓用殭屍檢測並記錄分配歷史記錄和引用計數。
  • 運行您的應用程序,執行重新發布問題所需的步驟
  • 儀器將在發送殭屍消息時停止執行。
  • 然後找到已分配消息的分配/對象,並遍歷其生存期/參考計數歷史。

這使得定位過度釋放的對象非常容易找到(例如從某些情況下的幾小時到幾分鐘)。

相關問題