在reloadData之后NSMutableArray变为nil

时间:2010-07-12 23:33:40

标签: iphone objective-c cocoa-touch uitableview nsmutablearray

在我正在开发的iPhone应用程序中,我从Web服务中获取一组数据,将其存储在可变数组中以显示在表中,并在没有网络时将其存储在核心数据中作为备份。

我的数组在应用程序中初始化:didFinishLaunchingWithOptions:如下所示 tableArray = [[NSMutableArray alloc] initWithCapacity:100];
然后在调用viewDidLoad之后填充数组,这意味着UITableView存在(通过检查调试器验证),并且在调用reloadData之前,我有NSLog打印出数组的内容,并且确定一切都在那里。

我的问题是在调用 reloadData之后,tableArray变为null,如tableView中的NSLog所示:numberOfRowsInSection:。

我完全不知道为什么会发生这种情况,尽管我只是在Cocoa中编程了几个月而且很容易丢失一些明显的东西。

编辑:更新了基本代码。

@interface MyAppDelegate : NSObject {
...
NSMutableArray *tableArray;
}
@property (nonatomic, retain) NSMutableArray *tableArray;
...
@end

@implementation MyAppDelegate
@synthesize tableArray

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    tableArray = [[NSMutableArray alloc] initWithCapacity:100];

    masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:[NSBundle mainBundle]];
    [masterViewController.tableView setDelegate:self];
    [masterViewController.tableView setDataSource:self];
    ...
}

然后在masterViewController的viewDidLoad中调用一个名为runWithNetwork的方法:

- (void)runWithNetwork {
    ...
    NSArray *backpackArray = [[mainDict objectForKey:@"items"] objectForKey:@"item"];
    NSLog(@"%i", [backpackArray count]);
    for (int a=0; a<[backpackArray count]; a++) {
    NSDictionary *itemDict = [backpackArray objectAtIndex:a];
        NSString *ID = [[itemDict valueForKey:@"defindex"] stringValue];
        NSString *level = [[itemDict valueForKey:@"level"] stringValue];
        NSString *quality = [[itemDict valueForKey:@"quality"] stringValue];
        NSString *inventory = [[itemDict valueForKey:@"inventory"] stringValue];
        NSNumber *uid = [NSNumber numberWithInt:a];

        //Insert new
        myItem = [NSEntityDescription insertNewObjectForEntityForName:@"Backpack" inManagedObjectContext:managedObjectContext_];
        [myItem setValue:level forKey:@"level"];
        [myItem setValue:inventory forKey:@"inventory"];
        [myItem setValue:quality forKey:@"quality"];
        [myItem setValue:uid forKey:@"uid"];

        //Link to item db
        NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id == %@", ID];
        [fetch setEntity:[NSEntityDescription entityForName:@"GlobalItems" inManagedObjectContext:managedObjectContext_]];
        [fetch setPredicate:predicate];

        item = [[managedObjectContext_ executeFetchRequest:fetch error:nil] objectAtIndex:0];
        [myItem setValue:item forKey:@"item"];

        [tableArray addObject:[item valueForKey:@"name"]]; //a series of nsstrings

    }
    NSLog(@"%@, %i", tableArray, [tableArray retainCount]); // all strings are printed correctly here, retaincount is 1

    [masterViewController.tableView reloadData];
}

然后我转到我的桌子方法:

- (NSInteger)tableView:(UITableView *)tView numberOfRowsInSection:(NSInteger)section {  
    NSLog(@"%@, %i", tableArray, [tableArray retainCount]);  //(null) printed, 0 for retaincount
    return [tableArray count];  //returns 0
}

tableView位于MasterViewController的xib中,并在那里正确链接。它只在MasterViewController中描述,并设置为IBOutlet。 tableArray仅在MyAppDelegate.h中描述,不会在其他任何地方重新创建。

2 个答案:

答案 0 :(得分:1)

正如我在评论中所说,很难弄清楚到底出了什么问题。但根据我在邮件列表等方面帮助人们的经验,像这样的bug的最常见原因是当你认为有一个时有两个不同的对象。例如,一个实例在nib中创建,另一个实例在其他地方的代码中手动创建。这可能值得一试。

答案 1 :(得分:1)

您的tableArray未被保留,因为您没有使用访问者进行设置。变化:

tableArray = [[NSMutableArray alloc] initWithCapacity:100];

为:

[self setTableArray:[[NSMutableArray alloc] initWithCapacity:100]];