2010-06-04 29 views
0

我有我有兩種方法在不同的類。一個是類方法,另一個是實例方法。我從實例方法調用類方法。當實例方法完成時,會給運行時錯誤「EXC_BAD_ACCESS」。NSArray運行時數組

#import "xmlObject.h" 
#import "textmeAppDelegate.h" 
@implementation Class1 
    - (void)method1 { 
       textmeAppDelegate *del = (textmeAppDelegate *)[[UIApplication sharedApplication] delegate]; 

       NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]]; 
       UIColor *color = [UIColor colorWithRed:[[bgColor objectAtIndex:3] floatValue] green:[[bgColor objectAtIndex:2] floatValue] blue:[[bgColor objectAtIndex:1] floatValue] alpha:[[bgColor objectAtIndex:0] floatValue]]; 
       CGContextSetFillColor(context, CGColorGetComponents([color CGColor])); 
       CGContextFillRect(context, rect); 
       [bgColor release]; 

     } 
    @end 

@implementation xmlObject 
     + (NSArray *) fetchImmediateChildrenValues:(NSMutableDictionary *) node { 
     NSMutableDictionary *tmp = [[node objectForKey:@"children"] retain]; 
     NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]]; 
     keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 
     NSMutableArray *pushArr = [[[NSMutableArray alloc] init] autorelease]; 
     NSString *val = [[NSString alloc] init]; 
     for(NSString *str in keys) { 
      val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"]; 
      [pushArr addObject:val]; 
     } 
     [val release]; 
     [keys release]; 

     return [NSArray arrayWithArray:pushArr]; 
     } 

@end 

代碼有什麼問題?同時也是應用崩潰的這行代碼 應用程序崩潰,如果我加入這一行

NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]]; 

如果我刪除應用程序運行速度流暢。

+0

'xmlObject'從哪裏來? – d11wtq 2010-06-04 08:51:10

+0

此外,'textmeAppDelegate'是一個有效的類型?它看起來更像是一個實例變量的名稱,而不是一個類型,但是您試圖將它用作類型。 – d11wtq 2010-06-04 08:53:03

+0

xmlObject是在文件開始處導入的類。和textmeAppDelegate是一個有效的類型,因爲它是我在我的應用程序的不同部分調用委託。 – 2010-06-04 09:49:37

回答

1

我對你的代碼有幾點評論。其中之一是你的崩潰的直接原因,但你至少還需要解決另一個問題。簡短的答案是,你通過釋放val和鍵。

NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]]; 

你並不需要在這裏創建一個新的數組,你可以簡單地寫:

NSArray *bgColor = [xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]; 

如果你這樣做,你不需要[bgColor release]進一步下跌。

NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]]; 
keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

這兩行泄漏第一個NSArray,你分配它,但你用排序後的版本直接覆蓋它。事實上,你可以簡單的寫:

keys = [[tmp allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

注意,你沒有自己的密鑰,所以你可以擺脫[keys release]線的進一步下跌。

NSString *val = [[NSString alloc] init]; 
for(NSString *str in keys) { 
    val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"]; 
    [pushArr addObject:val]; 
} 
[val release]; 

這是您的直接問題的來源。你首先分配一個新的字符串。然後,在循環的每次迭代中立即覆蓋它。所以分配的NSString泄漏。在每次迭代中,您都不擁有由[[tmp objectForKey:str] objectForKey:@"innertext"];返回的val,因此循環後的版本ov val不應該在那裏。

在附註上,objectForKey:返回一個id - 對NSString *的轉換是多餘的。大多數人都把它排除在外。

  [keys release]; 

回到上面的位置,我告訴你,你正在泄漏你的分配鍵?那麼你與你重寫的新版本密鑰並不擁有。因此你不能在這裏釋放密鑰。

return [NSArray arrayWithArray:pushArr]; 

這很好。我的偏好是:

return [[pushArray copy] autorelease]; 

但它只是一個風格問題。你也可以返回pushArray,但pushArray是可變的,調用者可以依賴返回值是不可變的。

+0

感謝百萬人的回覆並感謝萬億人解決問題。這讓我發瘋。你能告訴我爲什麼在應用程序啓動時,我在控制檯上得到了很多'malloc:*** object error 0x43181e0:double free'的錯誤 – 2010-06-04 13:36:09

+0

很可能在代碼的其他地方有很多類似的問題。我認爲你需要回顧大部分內容。 – JeremyP 2010-06-04 15:31:35

+0

我回顧了我的應用程序,牢記上面的要點,現在只剩下幾個漏洞。什麼可能是從整個應用程序中刪除泄漏的過程。 – 2010-06-05 09:42:24

1

用NSZombieEnabled設置測試你的代碼...它應該給你足夠的信息來解決你的問題。

+0

我啓用了NSZombieEnabled。你能告訴我如何得到「EXC_BAD_ACCESS」運行時錯誤的原因 – 2010-06-04 10:12:56

+0

EXC_BAD_ACCESS通常意味着你正在發送消息給釋放對象。 NSZombieEnabled將爲每個釋放對象放置一個虛擬對象,這將在釋放後通過消息時通知您。 檢查您的控制檯日誌... – Macmade 2010-06-04 10:16:23

+0

應用程序在開始時在控制檯上崩潰 *** - [CFString發佈]:發送到釋放實例的消息0x43385f0 – 2010-06-04 10:38:33