Я попытался добавить парсер TopSongs и файлы Core Data в свое приложение, и теперь оно успешно создается без ошибок или предупреждений. Однако, как только приложение загружается, оно падает, давая следующую причину:
ОБНОВЛЕНИЕ: у меня все работает, но мой TableView не показывает никаких данных, и приложение не реагирует на следующие точки останова.
Спасибо.
ОБНОВЛЕНИЕ: вот новый код, который не реагирует на точки останова.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)table {
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)viewDidUnload {
[super viewDidUnload];
self.tableView = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:self.managedObjectContext];
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellIdentifier = @"SongCell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
}
Incident *incident = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"#%d %@", @"#%d %@"), incident.title];
return cell;
}
- (void)tableView:(UITableView *)table didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[table deselectRowAtIndexPath:indexPath animated:YES];
self.detailController.incident = [fetchedResultsController objectAtIndexPath:indexPath];
[self.navigationController pushViewController:self.detailController animated:YES];
}
ОБНОВЛЕНИЕ: Вот код, в котором найдены все экземпляры выборки.
- (Category *)categoryWithName:(NSString *)name {
NSTimeInterval before = [NSDate timeIntervalSinceReferenceDate];
#ifdef USE_CACHING
// check cache
CacheNode *cacheNode = [cache objectForKey:name];
if (cacheNode != nil) {
// cache hit, update access counter
cacheNode.accessCounter = accessCounter++;
Category *category = (Category *)[managedObjectContext objectWithID:cacheNode.objectID];
totalCacheHitCost += ([NSDate timeIntervalSinceReferenceDate] - before);
cacheHitCount++;
return category;
}
#endif
// cache missed, fetch from store - if not found in store there is no category object for the name and we must create one
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:self.categoryEntityDescription];
NSPredicate *predicate = [self.categoryNamePredicateTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:name forKey:kCategoryNameSubstitutionVariable]];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchResults = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
NSAssert1(fetchResults != nil, @"Unhandled error executing fetch request in import thread: %@", [error localizedDescription]);
Category *category = nil;
if ([fetchResults count] > 0) {
// get category from fetch
category = [fetchResults objectAtIndex:0];
} else if ([fetchResults count] == 0) {
// category not in store, must create a new category object
category = [[Category alloc] initWithEntity:self.categoryEntityDescription insertIntoManagedObjectContext:managedObjectContext];
category.name = name;
[category autorelease];
}
#ifdef USE_CACHING
// add to cache
// first check to see if cache is full
if ([cache count] >= cacheSize) {
// evict least recently used (LRU) item from cache
NSUInteger oldestAccessCount = UINT_MAX;
NSString *key = nil, *keyOfOldestCacheNode = nil;
for (key in cache) {
CacheNode *tmpNode = [cache objectForKey:key];
if (tmpNode.accessCounter < oldestAccessCount) {
oldestAccessCount = tmpNode.accessCounter;
[keyOfOldestCacheNode release];
keyOfOldestCacheNode = [key retain];
}
}
// retain the cache node for reuse
cacheNode = [[cache objectForKey:keyOfOldestCacheNode] retain];
// remove from the cache
[cache removeObjectForKey:keyOfOldestCacheNode];
} else {
// create a new cache node
cacheNode = [[CacheNode alloc] init];
}
cacheNode.objectID = [category objectID];
cacheNode.accessCounter = accessCounter++;
[cache setObject:cacheNode forKey:name];
[cacheNode release];
#endif
totalCacheMissCost += ([NSDate timeIntervalSinceReferenceDate] - before);
cacheMissCount++;
return category;
}
А этот ...
- (void)fetch {
NSError *error = nil;
BOOL success = [self.fetchedResultsController performFetch:&error];
NSAssert2(success, @"Unhandled error performing fetch at SongsViewController.m, line %d: %@", __LINE__, [error localizedDescription]);
[self.tableView reloadData];
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Song" inManagedObjectContext:managedObjectContext]];
NSArray *sortDescriptors = nil;
NSString *sectionNameKeyPath = nil;
if ([fetchSectioningControl selectedSegmentIndex] == 1) {
sortDescriptors = [NSArray arrayWithObjects:[[[NSSortDescriptor alloc] initWithKey:@"category.name" ascending:YES] autorelease], [[[NSSortDescriptor alloc] initWithKey:@"rank" ascending:YES] autorelease], nil];
sectionNameKeyPath = @"category.name";
} else {
sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"rank" ascending:YES] autorelease]];
}
[fetchRequest setSortDescriptors:sortDescriptors];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:sectionNameKeyPath cacheName:@"SongsCache"];
}
return fetchedResultsController;
}