【发布时间】:2010-07-12 23:33:39
【问题描述】:
在我正在开发的 iPhone 应用程序中,我从 Web 服务获取一组数据,将其存储在可变数组中以显示在表格中,并将其存储在核心数据中作为没有网络时的备份。
我的数组在application:didFinishLaunchingWithOptions中初始化:如下tableArray = [[NSMutableArray alloc] initWithCapacity:100];
然后在调用 viewDidLoad 后填充数组,这意味着 UITableView 存在(通过检查调试器进行验证),并且在调用 reloadData 之前,我让 NSLog 打印出数组的内容,果然一切都在那里。
我的问题是 在 reloadData 被调用后,tableArray 变为 null,如 tableView:numberOfRowsInSection: 中的 NSLog 所示。
我完全不知道为什么会发生这种情况,尽管我只在 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 中描述,不会在其他任何地方重新创建。
【问题讨论】:
-
很奇怪,你的变量自发变成了
nil。您是否尝试使用 Guard Malloc 运行您的程序(运行菜单 -> 启用 Guard Malloc)以查看您是否在某处有缓冲区 voerflow? -
刚刚尝试过,我假设 GuardMalloc 找到的任何内容都会打印在控制台中?在这种情况下,那里的一切似乎都很好,我收到了 GM 的“欢迎”消息,然后一切都像以前一样被 NSLog 打印出来。
-
我想到了几种可能性,但是通过模糊描述您认为代码的工作方式很难弄清楚任何事情。查看代码(或仍然存在问题的简化版本)将更容易推断。
标签: iphone objective-c cocoa-touch uitableview nsmutablearray