これはおそらく非常に単純なアプリケーションですが、Objective-C (Java から来た) は初めてで、メモリ管理全体と "EXC_BAD_ACCESS" エラーが私の心を痛めています。
Core Dataを使用した通常のNavigationController iPhoneアプリがあります。AppDelegate で NSManagedObjectContext が作成され、RootViewController に渡されます。ビューはメインスレッドから直接検索されてテーブルにデータが入力されますが、それはうまく機能しているようです。
アプリはある種の RSS タイプのリーダーなので、アプリが起動するとすぐにスレッドを起動して新しいデータを取得し、ビューを更新します。
-(void)updateData:(id)sender {
UIActivityIndicatorView *activityIndicator =
[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[activityIndicator startAnimating];
UIBarButtonItem *activityItem =
[[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
[activityIndicator release];
self.navigationItem.leftBarButtonItem = activityItem;
[activityItem release];
// Start thread to update the data
[NSThread detachNewThreadSelector:@selector(doUpdateData) toTarget:self withObject:nil];
}
-(void)doUpdateData{
NSLog(@"Update data Thread (in 5 sec.)");
[NSThread sleepForTimeInterval:5];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
DataManager *data = [[DataManager alloc] initWithContext:managedObjectContext];
[data updateData];
[data release];
data=nil;
[self performSelectorOnMainThread:@selector(finishUpdateData) withObject:nil waitUntilDone:NO];
[pool release];
}
-(void)finishUpdateData{
self.navigationItem.leftBarButtonItem = updateBttn;
DataManager *data = [[DataManager alloc] initWithContext:managedObjectContext];
objects = [data getArticles];
[data release];
data=nil;
NSLog(@"Amount of records after update: %d", [objects count]);
[self.tableView reloadData];
}
問題は、これが機能しないことです。DataManager では、最初に設定を取得する必要があり、NSEntityDescription が作成されるとすぐに「EXC_BAD_ACCESS」を取得します。
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Setting" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"key" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchLimit:1];
.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
}
return fetchedResultsController;
}
別のスレッドとメモリプールで実行した結果、ManagedObjectContext へのポインタが間違っていると思います。それで、それが問題である場合、どのようにそのようなアプリケーションを作成しますか)、彼がスレッドする元の ManagedObjectContext 形式への参照を取得するにはどうすればよいですか?
[編集]私も使ってみました
iDomsAppDelegate *appDelegate = (iDomsAppDelegate *)[[UIApplication sharedApplication] delegate];
DataManager *data = [[DataManager alloc] initWithContext:appDelegate.managedObjectContext];
(他の投稿で示唆されているように)doUpdateDataで、しかしそれは同じ結果をもたらします