Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Core data NSFetchedResultsController:NSSortDescriptor(关系为键)将无法识别的选择器compare:发送到核心数据实体对象_Core Data_Foreign Keys_One To Many_Nssortdescriptor_Unrecognized Selector - Fatal编程技术网

Core data NSFetchedResultsController:NSSortDescriptor(关系为键)将无法识别的选择器compare:发送到核心数据实体对象

Core data NSFetchedResultsController:NSSortDescriptor(关系为键)将无法识别的选择器compare:发送到核心数据实体对象,core-data,foreign-keys,one-to-many,nssortdescriptor,unrecognized-selector,Core Data,Foreign Keys,One To Many,Nssortdescriptor,Unrecognized Selector,我试图在核心数据中保存一对多关系。用户决定是否需要将新的子列表对象附加到新的父对象。在另一种情况下,现有数据库条目用作父对象。在保存后的某些情况下,应用程序会崩溃 最终编辑:对不起,如果您介意我保留所有编辑,我仍然会保留。启蒙的过程相当复杂。毕竟我开始认为这是数据冲突。。。再次感谢,他为我指明了正确的方向:我仍在使用一个关系,使用nsfetchedresultscoontroller对核心数据实体进行排序和分组。我已经为我的实体类编写了一个有效的compare:方法,目前为止,我看不出它在工作。

我试图在核心数据中保存一对多关系。用户决定是否需要将新的子列表对象附加到新的父对象。在另一种情况下,现有数据库条目用作父对象。在保存后的某些情况下,应用程序会崩溃

最终编辑:对不起,如果您介意我保留所有编辑,我仍然会保留。启蒙的过程相当复杂。毕竟我开始认为这是数据冲突。。。再次感谢,他为我指明了正确的方向:我仍在使用一个关系,使用
nsfetchedresultscoontroller
对核心数据实体进行排序和分组。我已经为我的实体类编写了一个有效的
compare:
方法,目前为止,我看不出它在工作。我正要为我的问题写一个答案。对于您提供的有关此问题的任何信息警告,我将非常感激

编辑3:保存过程和用户警报似乎是该问题的附带问题。我现在放大了NSFetchedResultsController,并将一个关系(“检查”)用作
sectionNameKeyPath
。现在,我将尝试在我的
检查
实体类的类别中编写一个
比较:
方法。如果这也不起作用,那么除了关系之外,我还必须在我的
Image
实体类中写入一个可比较的值,并将其用于部分你们都同意吗?

编辑1:只有在询问用户是否需要新的检查并回答“是”后,才会发生崩溃。当没有用户提示时(当新检查的创建已由事实决定时)(无现有检查=是,现有检查未超时=否),也会输入相同的方法。在这些情况下,不会发生错误。必须是视图在警报视图打开时完成加载,然后集合视图及其NSFetchedResultsController加入到事件中

编辑2:感谢,这是调用堆栈。我不认为这是相关的,但视图控制器在集合视图中显示图像,每个检查的图像部分降序。因此,NSFetchedResultsController的部分键和排序描述符都在MOC更改通知后使用检查ion已被发送。使我的应用程序崩溃的不是保存:而是NSSortDescriptor(或者,公平地说,是我使用所有这些的方式)。


NSFetchedResultsController的代码:

#pragma mark - NSFetchedResultsController

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

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:NSStringFromClass([Image class]) inManagedObjectContext:[[HLSModelManager currentModelManager] managedObjectContext]];
    [fetchRequest setEntity:entity];

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

    // Edit the sort key, identical sort to section key path must be first criterion
    NSSortDescriptor *examinationSortDescriptor = [[NSSortDescriptor alloc] initWithKey:kexaminationSortDescriptor ascending:NO];
    NSSortDescriptor *editDateSortDescriptor = [[NSSortDescriptor alloc] initWithKey:keditDateSortDescriptor ascending:NO];

    NSArray *sortDescriptors =[[NSArray alloc] initWithObjects:examinationSortDescriptor, editDateSortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // 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:[[HLSModelManager currentModelManager] managedObjectContext] sectionNameKeyPath:kSectionNameKeyPath cacheName:NSStringFromClass([Image class])];
    aFetchedResultsController.delegate = self;
    m_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.
        HLSLoggerFatal(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return m_fetchedResultsController;
}

#pragma mark - NSFetchedResultsControllerDelegate - optional

/* Asks the delegate to return the corresponding section index entry for a given section name.  Does not enable NSFetchedResultsController change tracking.
 If this method isn't implemented by the delegate, the default implementation returns the capitalized first letter of the section name (seee NSFetchedResultsController sectionIndexTitleForSectionName:)
 Only needed if a section index is used.
 */
- (NSString *)controller:(NSFetchedResultsController *)controller sectionIndexTitleForSectionName:(NSString *)sectionName
{
    return sectionName;
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    // In the simplest, most efficient, case, reload the table view.
    [[self collectionView] reloadData];
}

/* THE OTHER DELEGATE METHODS ARE ONLY FOR UITableView! */

保存检查(现有或新)和新图像的代码:

-(BOOL)saveNewImage
{
    BOOL done = NO;

    // remove observer for notification after alert
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kExaminationTimedoutAlertDone object:nil];

    Examination * currentExamination = [self getCurrentExamination];

    if ([self userWantsNewExamination] == YES)
    { // if an examination was found
        if (currentExamination != nil)
        { // if the found examination is not closed yet
            if ([currentExamination endDate] == nil)
            { // close examination & save!
                [currentExamination closeExamination];
                NSError *savingError = nil;
                [HLSModelManager saveCurrentModelContext:(&savingError)];

                if (savingError != nil)
                {
                    HLSLoggerFatal(@"Failed to save old, closed examination: %@, %@", savingError, [savingError userInfo]);
                    return NO;
                }
            }
        }
        currentExamination = nil;
    }

    // the examination to be saved, either new or old
    Examination * theExamination = nil;

    // now, whether user wants new examination or no current examination was found - new examination will be created
    if (currentExamination == nil)
    {
        // create new examination
        theExamination = [Examination insert];
        if (theExamination == nil)
        {
            HLSLoggerFatal(@"Failed to create new examination object.");
            currentExamination = nil;
            return NO;
        }

        // set new examinations data
        [theExamination setStartDate: [NSDate date]];
    }
    else
    {
        theExamination = currentExamination;
    }

    if (theExamination == nil)
    { // no image without examination!
        HLSLoggerFatal(@"No valid examination object.");
        return NO;
    }

    Image *newImage = [Image insert];

    if (newImage != nil)
    {
        // get users last name from app delegate
        AppDelegate * myAppDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];

        // set image data
        [newImage setEditUser: [[myAppDelegate user] lastName]];
        [newImage setEditDate: [NSDate date]];
        [newImage setExamination: theExamination];
        [newImage setImage: [self stillImage]];
        [newImage createImageThumbnail];

        // update edit data
        [theExamination setEditUser: [[myAppDelegate user] lastName]];
        [theExamination setEditDate: [NSDate date]];
        // unnecessary! CoreData does it automatically! [theExamination addImagesObject:newImage];

        //! Important: save all changes in one go!
        NSError *savingError = nil;
        [HLSModelManager saveCurrentModelContext:(&savingError)];

        if (savingError != nil)
        {
            HLSLoggerFatal(@"Failed to save new image + the examination: %@, %@", savingError, [savingError userInfo]);
        }
        else
        {
            // reload data into table view
            [[self collectionView] reloadData];
            return YES;
        }
    }
    else
    {
        HLSLoggerFatal(@"Failed to create new image object.");
        return NO;
    }

    return done;
}

错误:

2013-05-22 17:03:48.803 MyApp[11410:907] -[Examination compare:]: unrecognized selector sent to instance 0x1e5e73b0
2013-05-22 17:03:48.809 MyApp[11410:907] CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  -[Examination compare:]: unrecognized selector sent to instance 0x1e5e73b0 with userInfo (null)
2013-05-22 17:03:48.828 MyApp[11410:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Examination compare:]: unrecognized selector sent to instance 0x1e5e73b0'

以下是实体类文件:

//
//  Examination.h
//  MyApp
//

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

@class Image;

@interface Examination : NSManagedObject

@property (nonatomic, retain) NSDate * editDate;
@property (nonatomic, retain) NSString * editUser;
@property (nonatomic, retain) NSDate * endDate;
@property (nonatomic, retain) NSDate * startDate;
@property (nonatomic, retain) NSSet *images;
@end

@interface Examination (CoreDataGeneratedAccessors)

- (void)addImagesObject:(Image *)value;
- (void)removeImagesObject:(Image *)value;
- (void)addImages:(NSSet *)values;
- (void)removeImages:(NSSet *)values;

@end

此错误与将数据保存到主运行中心无关

由于新图像数据的保存在上一个视图控制器的prepareForSegue中触发,并且用户警报为下一个视图控制器提供了完成加载的时间,还创建了NSFetchedResultsController及其与委托的连接,因此在保存到MOC和o的临时上下文中引发了异常仅在用户警报之后

NSFetchedResultsController仅在这种情况下才开始侦听MOC的更改。似乎如果收到MOC更改的警报,它将只获取更改,然后才需要将新数据与现有数据进行比较。非常欢迎提供更多信息

然后,因为我设置了一个排序描述符(以及
sectionNameKeyPath
)在我的核心数据实体类中,由于没有提供对实体对象进行排序的方法,NSFetchedResultsController无法继续。回想起来,这一切似乎如此简单和自然,我真的对我的解决方案的简单性产生了怀疑

我觉得有趣的是,它可以在不受任何更改干扰的情况下一次性获取初始数据。毕竟它使用的是同一个NSSortDescriptor。有什么想法吗

这是我的解决方案:

//
//  MyCategoryExamination.m
//  MyApp
//

#import "MyCategoryExamination.h"

@implementation Examination (MyCategoryExamination)

- (NSComparisonResult)compare:(Examination *)anotherExamination;
{
    return [[self startDate] compare:[anotherExamination startDate]];
}

@end

请告诉我是否有问题。

此错误与将数据保存到主运行中心无关

由于新图像数据的保存在上一个视图控制器的prepareForSegue中触发,并且用户警报为下一个视图控制器提供了完成加载的时间,还创建了NSFetchedResultsController及其与委托的连接,因此在保存到MOC和o的临时上下文中引发了异常仅在用户警报之后

NSFetchedResultsController仅在这种情况下才开始侦听MOC的更改。似乎如果收到MOC更改的警报,它将只获取更改,然后才需要将新数据与现有数据进行比较。非常欢迎提供更多信息

然后,因为我设置了一个排序描述符(以及
sectionNameKeyPath
)在我的核心数据实体类中,由于没有提供对实体对象进行排序的方法,NSFetchedResultsController无法继续。回想起来,这一切似乎如此简单和自然,我真的对我的解决方案的简单性产生了怀疑

我觉得有趣的是,它可以在不受任何更改干扰的情况下一次性获取初始数据。毕竟它使用的是同一个NSSortDescriptor。有什么想法吗

这是我的解决方案:

//
//  MyCategoryExamination.m
//  MyApp
//

#import "MyCategoryExamination.h"

@implementation Examination (MyCategoryExamination)

- (NSComparisonResult)compare:(Examination *)anotherExamination;
{
    return [[self startDate] compare:[anotherExamination startDate]];
}

@end

请告诉我这是否有问题。

我再次检查了它:只有在要求用户在警报视图中做出决定后,才会出现错误。当在没有警报视图的情况下输入分支
[self-UserWantsNewExamition]==YES
时,它只保存数据(???)。尝试在Objective-C异常上设置断点。您将点击