1

我正在使用 github 上的一个项目,它可以让我使用NSFetchedResultsControllerand UICollectionView,该项目就是这个

在我的项目中,我有一个带有两个实体的核心数据,Element并且Document,和之间存在一对多的关系ElementDocument所以一个Element可以有更多Document,但一个Document只能有一个Element,然后我在下面这样做AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.

ElementViewController *elementView = [[ElementViewController alloc] initWithNibName:@"ElementViewController" bundle:nil];
elementView.managedObjectContext = self.managedObjectContext;

DocumentViewController *documentView = [[DocumentViewController alloc] initWithNibName:@"DocumentViewController" bundle:nil];
documentView.managedObjectContext = self.managedObjectContext;

elementView.documentView = documentView;

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:elementView];

self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
 }

这是应用程序委托,然后ElementViewController我有一个UICollectionViewwith NSFetchedResultsController,一切正常,当我选择 a 时,UICollectionViewCell我打开DocumentViewController

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{

self.documentView.element = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.navigationController pushViewController:self.documentView animated:YES];

}

那么这是我的DocumentViewController.h

#import <UIKit/UIKit.h>
#import "Element.h"

@interface DocumentViewController : UIViewController <NSFetchedResultsControllerDelegate>

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;

@property (strong, nonatomic) Element *element;

@end

而且在这里我还有标题NSFetchedResultsController谓词中的过滤器:Element

- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];

// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"docDate" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];

[fetchRequest setSortDescriptors:sortDescriptors];

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"SUBQUERY(element, $b, $b.name == %@).@count > 0", self.element.name]];

// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    // Replace this implementation with code to handle the error appropriately.
    // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return _fetchedResultsController;
}

然后我还添加了这个:

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];

[self reloadCollectionView];

[self addDocument];
}

- (void)reloadTableView
{
self.fetchedResultsController = nil; //Because not search every time for different Element
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
    NSLog(@"Error in search %@, %@", error, [error userInfo]);
} else {
    [self.collectionView reloadData];
}
}

然后在 viewWillAppear 中有addDocument方法:

- (void)addDocument
{
Document *document = (Document *)[NSEntityDescription
                                          insertNewObjectForEntityForName:@"Document"
                                          inManagedObjectContext:self.managedObjectContext];

[document setDocName:[title contents]];
[document setElement:self.element]; //here the app crash
}

我收到这些错误:

    CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  Can't perform collection evaluate with non-collection object. with userInfo (null)
2013-01-25 10:28:56.392 App[383:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can't perform collection evaluate with non-collection object.'

任何人都可以帮助我吗?

编辑:这是 NSManagedObjectClass:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Document;

@interface Element : NSManagedObject

@property (nonatomic, retain) NSString * dateFormat;
@property (nonatomic, retain) NSString * dateFormat2;
@property (nonatomic, retain) id img;
@property (nonatomic, retain) NSDate * imgDate;
@property (nonatomic, retain) NSString * imgUrl;
@property (nonatomic, retain) NSString * language;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * name2;
@property (nonatomic, retain) NSString * pathDocuments;
@property (nonatomic, retain) NSNumber * releaseDateWeek;
@property (nonatomic, retain) NSNumber * type;
@property (nonatomic, retain) NSSet *documents;
@end

@interface Element (CoreDataGeneratedAccessors)

- (void)addDocumentsObject:(Document *)value;
- (void)removeDocumentsObject:(Document *)value;
- (void)addDocuments:(NSSet *)values;
- (void)removeDocuments:(NSSet *)values;

@end

@interface ImageToDataTransformer : NSValueTransformer {
}
@end

Document.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Element;

@interface Document : NSManagedObject

@property (nonatomic, retain) NSDate * docDate;
@property (nonatomic, retain) id docImage;
@property (nonatomic, retain) NSString * docName;
@property (nonatomic, retain) NSString * docPath;
@property (nonatomic, retain) NSNumber * docSize;
@property (nonatomic, retain) NSString * docUrl;
@property (nonatomic, retain) NSNumber * isDownloading;
@property (nonatomic, retain) NSNumber * isStored;
@property (nonatomic, retain) NSNumber * pageNumber;
@property (nonatomic, retain) NSString * password;
@property (nonatomic, retain) NSNumber * progressBar;
@property (nonatomic, retain) Element *element;

@end
4

1 回答 1

2

问题似乎在于:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"SUBQUERY(element, $b, $b.name == %@).@count > 0", self.element.name]];

'element' 不解析为集合(根据 SUBQUERY 的要求),而只是一个对象。

请参阅:http: //developer.apple.com/library/Mac/#documentation/Cocoa/Reference/Foundation/Classes/NSExpression_Class/Reference/NSExpression.html

于 2013-01-25T10:04:06.280 回答