Subclassing with CoreData and UITableviewController
I'm trying to subclass UITableViewController to minimize my code.
Basically I have all code in the super class exempt for the FetchedResultController, which I override in my subclasses.
It worked without this "split" but now it returns an EXC_BAD_ACCESS message.
Here is the code in my subclass:
- (NSFetchedResultsController *)fetchedResultsController
{
if (super.fetchedResultsController != nil)
{
return super.fetchedResultsController;
}
id delegate = [[UIApplication sharedApplication] delegate];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Question" inManagedObjectContext:[delegate managedObjectContext]];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor*sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"up_vote_count" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//next line returns EXC_BAD_ACCESS
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[delegate manag开发者_如何学CedObjectContext] sectionNameKeyPath:nil cacheName:@"Root2"];
aFetchedResultsController.delegate = self;
super.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return super.fetchedResultsController;
}
I'm curious if I should use super. or self. but self. crashed in the if statement.
-- EDIT --
Here is the @interface of the superclass. My subclass doesn't contain anything except of the overwritten methods.
@interface CoreDataTableView : UITableViewController <NSFetchedResultsControllerDelegate> {
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end
self. crashed in the if statement
That is because you're recursively calling the fetchedResultsController
method into an infinite loop.
Now, there are a few other problems.
First, I would suggest splitting that method into 2 parts:
- initializing the fetched results controller
- fetching the data
Also, your fetchRequest
is never released. Nor is aFetchedResultsController
. You own both of these objects inside that method, so you must release them to prevent leaks.
Based on these remarks, here's how the code would look:
- (NSFetchedResultsController *)fetchedResultsController
{
// In this method, because it's overriding the accessor in the super-class,
// you must use |super.fetchedResultsController|,
// otherwise you will trigger an infinite loop!
if (super.fetchedResultsController != nil)
{
return super.fetchedResultsController;
}
id delegate = [[UIApplication sharedApplication] delegate];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// ...
// omitted the other details...
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[delegate managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root2"];
aFetchedResultsController.delegate = self;
super.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
return super.fetchedResultsController;
}
- (void)fetch
{
NSError *error = nil;
// using |self| here is OK, because you're referring to the current object's method
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
As for using super
vs self
:
super.foo
or[super foo]
starts to look for methodfoo
in the super-classself.foo
or[self foo]
looks for methodfoo
in the current object's class
In your case, it wouldn't make much difference except for the fact that self.fetchedResultsController
would trigger an infinite loop as I mentioned before, if used inside the accessor.
I hope I got this right and that it cleared things up for you...
精彩评论