2011-03-02 68 views
1

我寫了一個函數來返回一個字符串到一個目錄路徑。我得到一個EXC_BAD_ACCESS,我認爲這個函數是原因。我需要保留nsstring什麼的?分配NSString時得到一個EXC_BAD_ACCESS

-(void) getRemoteFiles:(NSMutableArray *) M 
{ 
    [self createFileToAppDirectory]; 

    if (!networkqueue) { 
     networkqueue:[[[ASINetworkQueue alloc] init] autorelease]; 
    } 

    [[self networkQueue] cancelAllOperations]; 

    [self setNetworkQueue:[ASINetworkQueue queue]]; 
    [[self networkQueue] setDelegate:self]; 
    [[self networkQueue] setRequestDidFinishSelector:@selector(requestFinished:)]; 
    [[self networkQueue] setRequestDidFailSelector:@selector(requestFailed:)]; 
    [[self networkQueue] setQueueDidFinishSelector:@selector(queueFinished:)]; 


    int i; 

    for (i=0; i<[M count]; i++) { 
     NSString *url=[M objectAtIndex:i]; 
     NSString* theFileName = [url lastPathComponent]; 
     NSString *safestring=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
     if ([theFileName isEqualToString:@"nothing"]==NO) { 

      ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:safestring]]; 
      //think this is causing the problem 
      NSString *savepath=[self getDirectoryPathForFileName:theFileName]; 
      //[request setDownloadDestinationPath:savepath]; 
      [[self networkQueue] addOperation:request]; 
     } 

    } 

    [[self networkQueue] go]; 
    //error thrown after this point 


} 
-(NSString *)getDirectoryPathForFileName:(NSString *)filename 

{ 
    NSFileManager *filemgr; 
    NSArray *dirPaths; 
    NSString *docsDir; 
    NSString *newDir; 
    BOOL isDir; 


    filemgr =[NSFileManager defaultManager]; 
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

    docsDir = [dirPaths objectAtIndex:0]; 

    newDir = [docsDir stringByAppendingPathComponent:@"remix_data"]; 
    if ([filemgr fileExistsAtPath:newDir isDirectory:&isDir]==NO) { 
     NSLog(@"dir should exist but does not... go funt dat"); 
    } 

    NSString *localFilePath = [newDir stringByAppendingPathComponent:filename]; 
    [filemgr release]; 
    [docsDir release]; 
    [newDir release]; 
    return localFilePath; 
} 
+0

你沒有對filemgr,docsDir和newDir執行alloc/init。那麼你爲什麼要釋放它們? – 2011-03-02 10:26:34

+0

我還在學習內存管理,代碼來自一個例子。我猜這個例子是錯的? – dubbeat 2011-03-02 10:28:17

回答

2

不,你實際上是過度釋放。在getDirectoryPathForFileName中,您將釋放docsDir(例如),儘管您從未保留它。你將它從dirPaths數組中取出,這不會增加保留計數。通過釋放它,你可以減少保留計數,可能爲零,這將釋放字符串,而數組仍然認爲它保留它。下次數組使用該字符串進行操作時,您的應用程序將崩潰。只要刪除docsDir和newDir的發佈呼叫,你應該很好...

+0

我會試試這個。我對nsstring的使用對你來說似乎沒問題嗎? – dubbeat 2011-03-02 10:34:57

+0

是的,對我來說這似乎是完全合理的,沒有任何場合你沒有必要或錯誤地使用它。你只需要習慣那些內存管理問題,但這不是NSString相關的......不要擔心,你會習慣它!一個經驗法則:如果您使用以init開頭的方法創建它,或者如果您手動保留它,則只需要釋放某些內容。 – Toastor 2011-03-02 10:43:35

+0

解決方案正確和解釋有幫助 – dubbeat 2011-03-02 11:08:03

-1

是它更好地保留字符串並在使用後釋放它。由於您沒有分配字符串,因此不建議釋放字符串docsDirnewDir。它們是自動釋放對象。

1

一如往常當有人有EXC_BAD_ACCESS問題,我建議NSZombie。在你的特定情況下,很容易看出它爲什麼會崩潰,因爲你發佈的東西沒有先分配或保留它。你應該只發布你自己分配或保留的東西。

如果你在未來得到一個EXC_BAD_ACCESS的問題,這是不容易搞清楚,這裏是如何使用NSZombie:

要激活NSZombie做到以下幾點:

  1. 獲取的信息可執行文件。
  2. 轉到參數選項卡。
  3. 在「變量在環境中進行設置:」部分添加:

名稱:NSZombieEnabled 值:是

然後運行你的應用程序像往常一樣,當它崩潰,它會告訴你哪個釋放對象收到釋放消息。

+1

並且不要忘記隨後禁用殭屍。你不想爲了找出你離開NSZombies而追查半小時的泄漏。就像我昨天做的一樣。 – 2011-03-02 10:43:40

+0

這是一個很好的觀點。 – 2011-03-02 10:50:57