使用UICollectionView和NSFetchedResultsController不保存(U

2019-10-17 15:34发布

我使用的是项目在github,让我使用NSFetchedResultsControllerUICollectionView ,该项目是这个

在我的项目我有两个实体,一个核心数据ElementDocument ,还有之间的关系一对多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我有一个UICollectionViewNSFetchedResultsController ,所有工程确定,当我选择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

Answer 1:

这个问题看起来是在:

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

“元素”未解析为一个集合(所要求的SUBQUERY),而仅仅是一个单一的对象。

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



文章来源: Use UICollectionView and NSFetchedResultsController doesn't save