使用UICollectionView和NSFetchedResultsController不保存 [英] Use UICollectionView and NSFetchedResultsController doesn't save

查看:209
本文介绍了使用UICollectionView和NSFetchedResultsController不保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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的要求),而只是一个对象。



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


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.

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

这篇关于使用UICollectionView和NSFetchedResultsController不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆