2011-06-01 95 views
0

我有導航應用程序與3層次的層次。我的第一級是tabel視圖控制器。該控制器的nib文件是「TableView」。我在這裏遇到問題。我的代碼是這樣的:釋放對象的問題

RootViewController的

#import "RootViewController.h" 
#import "SubCategory.h" 
#import "OffersViewController.h" 

@implementation RootViewController 

@synthesize subCategories; 
@synthesize offersView; 

- (void)dealloc 
{ 
    NSLog(@"root dealloc"); 
    //[subCategories release]; 
    [super dealloc]; 
} 

- (void)viewDidLoad 
{ 
    NSLog(@"root view load"); 
    [super viewDidLoad]; 
    self.title = @"Sub Categories"; 

    NSString *jsonArray = [NSString stringWithFormat:@"{ " 
         @" \"sub-categories\": { " 
         @" \"parent\": \"1\", " 
         @" \"count\": \"2\", " 
         @" \"sub-category\": [{ " 
         @" \"id\": \"1\", " 
         @" \"name\": \"Buy\" " 
         @" }, " 
         @" { " 
         @" \"id\": \"2\", " 
         @" \"name\": \"Sell\" " 
         @" }] " 
         @" } " 
         @" }"]; 

    SubCategory* categories = [[SubCategory alloc] init]; 
    subCategories = categories; 
    [subCategories parseJSON:jsonArray]; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    NSLog(@"root sections"); 
return 1; 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    NSLog(@"root numberOfRows"); 
return [subCategories.subCategoryName count]; 
} 


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"root didSelectRow"); 
    OffersViewController * offers = [[OffersViewController alloc] initWithNibName:@"OffersView" bundle:nil]; 

    offersView = offers; 
    // I have exception on this row. exception is: 
    //-[__NSArrayI objectAtIndex:]: message sent to deallocated instance 0x4b04c00 
    offersView.title = [NSString stringWithFormat:@"%@", [subCategories.subCategoryName objectAtIndex:indexPath.row]]; 

    [self.navigationController pushViewController:offersView animated:YES]; 

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"root cellForRow"); 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cachedCell"]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] init] autorelease]; 
    } 

    cell.textLabel.text = [subCategories.subCategoryName objectAtIndex:indexPath.row]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

return cell; 
} 

@end 

子類別

#import "SubCategory.h" 
#import "JSON.h" 

@implementation SubCategory 

@synthesize parentId; 
@synthesize count; 
@synthesize subCategoryId; 
@synthesize subCategoryName; 


- (void) parseJSON: (NSString*) jsonArray { 
    NSDictionary *results = [jsonArray JSONValue]; 

    NSString *parent = (NSString*) [[results objectForKey:@"sub-categories"] objectForKey:@"parent"]; 
    parentId = [parent intValue]; 

    NSString *cnt = (NSString*) [[results objectForKey:@"sub-categories"] objectForKey:@"count"]; 
    self.count = [cnt intValue]; 

    NSDictionary *subCategories = [[results objectForKey:@"sub-categories"] objectForKey:@"sub-category"]; 


    NSMutableArray *namesArray = [[NSMutableArray alloc] initWithCapacity:[subCategories count]]; 
    NSMutableArray* idArray = [[NSMutableArray alloc] initWithCapacity:[subCategories count]]; 

    for (NSDictionary *subCategory in subCategories) {   
     [idArray addObject:[subCategory objectForKey:@"id"]]; 
     [namesArray addObject:[subCategory objectForKey:@"name"]]; 
    } 

    subCategoryId = [NSArray arrayWithArray:idArray]; 
    subCategoryName = [NSArray arrayWithArray:namesArray]; 

    [idArray release]; 
    [namesArray release]; 
//[parent release]; 
//[cnt release]; 
} 

@end 

我不知道爲什麼我的對象被釋放。有人能幫我嗎。

編輯:添加子類別代碼

+0

我們能看到你的'SubCategory'代碼?我認爲問題在那裏。 – jtbandes 2011-06-01 05:40:04

+0

我在帖子中編輯它 – 2011-06-01 05:43:44

回答

1

這裏的問題:

NSMutableArray *namesArray = [[NSMutableArray alloc] initWithCapacity:[subCategories count]]; 
NSMutableArray* idArray = [[NSMutableArray alloc] initWithCapacity:[subCategories count]]; 

... 

subCategoryId = [NSArray arrayWithArray:idArray]; 
subCategoryName = [NSArray arrayWithArray:namesArray]; 

[idArray release]; 
[namesArray release]; 

在這一點上,subCategoryIdsubCategoryName被自動釋放。這意味着在parseJSON:方法結束後它們將無法訪問。你有兩個選擇:

// Because idArray and namesArray are already retained (you alloc'd them) 
subCategoryId = idArray; 
subCategoryName = namesArray; 

或:

... 
// this is equivalent to what you have now, except these two will be retained. 
// this is different from the above because subCategoryId and subCategoryName are now NSArrays, whereas above they were NSMutableArrays. 
subCategoryId = [idArray copy]; 
subCategoryName = [namesArray copy]; 
... 
+0

非常感謝!這工作完美:) – 2011-06-01 05:53:45

0

子類別類別的範圍只是你的viewDidLoad。當你犯了一個淺拷貝,它/或複製將無法使用你的範圍之內,你需要保留它,它像

subCategories = [categories retain]; 

而且分配給子類別的時候,你可以放棄使用子類別分類的。相反,這樣做:

subCategories = [[SubCategory alloc] init];  
[subCategories parseJSON:jsonArray]; } 
+0

這是不正確的。 'categories'已經被保留了(它是用'alloc'製作的),所以'subCategories = categories'這行會保留這個。 – jtbandes 2011-06-01 05:48:19

+0

@jbantes你是對的,我還沒有看到子類(在更新之前),並認爲它在這裏必然會出錯。 – ophychius 2011-06-01 09:24:31