使用UICollectionView和NSFetchedResultsController不保存 [英] Use UICollectionView and NSFetchedResultsController doesn't save
问题描述
我在github上使用一个项目,让我使用 NSFetchedResultsController
和 UICollectionView
a href =https://github.com/AshFurrow/UICollectionView-NSFetchedResultsController =nofollow>此
在我的项目中,我有一个具有两个实体元素
和文档
的核心数据,在元素
和文档
,因此元素
可以有更多
,但是文档
只能有一个 Element
code> AppDelegate :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions :(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//在应用程序启动后覆盖自定义点。
ElementViewController * elementView = [[ElementViewController alloc] initWithNibName:@ElementViewControllerbundle:nil];
elementView.managedObjectContext = self.managedObjectContext;
DocumentViewController * documentView = [[DocumentViewController alloc] initWithNibName:@DocumentViewControllerbundle:nil];
documentView.managedObjectContext = self.managedObjectContext;
elementView.documentView = documentView;
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:elementView];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
这是App委托,然后在 ElementViewController
我有一个 UICollectionView
与 NSFetchedResultsController
,并且所有工作确定,当我选择 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>
#importElement.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
,元素
标题的谓语中的过滤器:
- (NSFetchedResultsController *)fetchedResultsController
{
if(_fetchedResultsController!= nil){
return _fetchedResultsController;
}
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
//根据需要编辑实体名称。
NSEntityDescription * entity = [NSEntityDescription entityForName:@DocumentinManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
//将批量大小设置为合适的数量。
[fetchRequest setFetchBatchSize:20];
//根据需要编辑排序键。
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@docDateascending:NO];
NSArray * sortDescriptors = @ [sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@SUBQUERY(element,$ b,$ b.name ==%@)。@ count> 0,self.element.name]];
//如果适当,编辑段名称键路径和缓存名称。
//节的名称键路径的nil表示没有节。
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]){
//用代码替换这个实现,以适当地处理错误。
// abort()导致应用程序生成崩溃日志并终止。您不应在运送应用程序中使用此功能,但在开发过程中可能很有用。
NSLog(@未解析的错误%@,%@,错误,[错误userInfo]);
abort();
}
return _fetchedResultsController;
}
然后我也添加了这样:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self ReloadCollectionView];
[self addDocument];
}
- (void)reloadTableView
{
self.fetchedResultsController = nil; //因为不是每次都搜索不同的元素
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]; //这里应用程序崩溃
}
我收到这些错误:
CoreData:错误:严重的应用程序错误。在核心数据更改处理期间捕获异常。这通常是NSManagedObjectContextObjectsDidChangeNotification的观察器中的错误。无法对非集合对象执行集合求值。使用userInfo(null)
2013-01-25 10:28:56.392 App [383:c07] ***由于未捕获异常NSInternalInconsistencyException终止应用程序,原因:集合对象。
任何人都可以帮助我?
EDIT:
这是NSManagedObjectClass:
#import< Foundation / Foundation.h>
#import< CoreData / CoreData.h>
@class文档;
@interface元素: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元素(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元素;
@interface文档: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
问题看起来是这样的:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@SUBQUERY(element,$ b,$ b.name ==%@)。@ count> 0,self.element.name]];
'element'不能解析为一个集合(按照SUBQUERY的要求),而只是一个对象。
I'm using a project find on github that lets me use NSFetchedResultsController
and UICollectionView
, the project is this
in my project i have a Core Data with two Entity, Element
and Document
, there is a relationship one to many between Element
and Document
, so an Element
can have more Document
, but a Document
can have only one Element
, then i do this in the 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;
}
this is the App delegate, then in ElementViewController
i have a UICollectionView
with NSFetchedResultsController
, and all works ok, when i select a UICollectionViewCell
i open the DocumentViewController
:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
self.documentView.element = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.navigationController pushViewController:self.documentView animated:YES];
}
then this is my 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
And also here i have the NSFetchedResultsController
, the filter in the predicate for the Element
title:
- (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;
}
and then i have add also this:
- (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];
}
}
then in the viewWillAppear there is the addDocument
method:
- (void)addDocument
{
Document *document = (Document *)[NSEntityDescription
insertNewObjectForEntityForName:@"Document"
inManagedObjectContext:self.managedObjectContext];
[document setDocName:[title contents]];
[document setElement:self.element]; //here the app crash
}
and i receive these error:
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.'
anyone can help me?
EDIT: This is the 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
The problem looks to be that that in:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"SUBQUERY(element, $b, $b.name == %@).@count > 0", self.element.name]];
'element' does not resolve to a collection (as required by SUBQUERY), but merely a single object.
这篇关于使用UICollectionView和NSFetchedResultsController不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!