8

我遇到了一个问题,即我的应用程序崩溃并出现以下异常:

ABC[1936:c07] *由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[<_NSObjectID_48_0 0xb63e310> valueForUndefinedKey:]:此类不符合键 ID 的键值编码。”

这个异常的奇怪问题是使用iOS5时不会发生。请参阅下面发生异常的代码:

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

if ((self.sectionInfoArray == nil) ||
    ([self.sectionInfoArray count] != [self numberOfSectionsInTableView:self.tableView]))
{
    NSMutableArray *infoArray = [[NSMutableArray alloc] init];

    for (Tour *tour in self.tours)
    {
        SectionInfo *sectionInfo = [[SectionInfo alloc] init];
        sectionInfo.tour = tour;
        sectionInfo.open = NO;

        NSLog(@"Tour Details Count %@", [[tour tourDetails] objectAtIndex:0]);

        NSNumber *defaultRowHeight = [NSNumber numberWithInteger:DEFAULT_ROW_HEIGHT];
        NSInteger countOfQuotations = [[sectionInfo.tour tourDetails] count];

        for (NSInteger i = 0; i < countOfQuotations; i++)
        {
            [sectionInfo insertObject:defaultRowHeight inRowHeightsAtIndex:i];
        }

        [infoArray addObject:sectionInfo];
    }

    self.sectionInfoArray = infoArray;
}

}

是否会因为我在类 Tour 中定义了一个获取的属性而导致这个异常,该类获取了一个 TourDetail 类的数组。请参阅以下两个类的实现代码:

    #import "Tour.h"
#import "TourDetail.h"

@implementation Tour

@dynamic background_url;
@dynamic id;
@dynamic summary;
@dynamic title;
@dynamic tour_tourdetail;

@dynamic tourDetails;

@end

#import "TourDetail.h"


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

@class TourDetail;

@interface Tour : NSManagedObject

@property (nonatomic, retain) NSString * background_url;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSString * summary;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) TourDetail *tour_tourdetail;

@property (nonatomic, retain) NSArray *tourDetails;

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


@interface TourDetail : NSManagedObject

@property (nonatomic, retain) NSString * audiofile;
@property (nonatomic, retain) NSString * detail;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * lattitude;
@property (nonatomic, retain) NSNumber * longitude;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSNumber * tour_id;
@property (nonatomic, retain) NSManagedObject *tourdetail_tour;

@end



@implementation TourDetail

@dynamic audiofile;
@dynamic detail;
@dynamic id;
@dynamic lattitude;
@dynamic longitude;
@dynamic title;
@dynamic tour_id;
@dynamic tourdetail_tour;

@end

对此问题的任何帮助将不胜感激。因为我不知道如何解决这个问题。

谢谢,迈克尔

更新:

当我删除 Fetched 属性时,iOS6 不会发生异常。请参阅我在下面配置的谓词:

获取的属性 tourDetails 谓词 tour_id == $FETCH_SOURCE.id

你能看到我在设置这个谓词时做错了什么吗?我的目标是使用它,以便我可以为每个 tour_id 返回一个 TourDetail 对象数组,该对象对 Tour 表中的 id 列进行数学运算。

更新:

我已经能够诊断出由于谓词而引发了异常,因为当我分别调用两个表时,没有引发异常。你能看出我创建的谓词有什么问题吗?

请参阅下面的代码,显示我如何从 Core Data DB 中检索对象:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [DrivingToursContent setupStaticData];

    self.tableView.sectionHeaderHeight = HEADER_HEIGHT;
    _openSectionIndex = NSNotFound;

    self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"custombackground.ptoung"]];

    self.managedObjectContext = [[BaseCoreDataController sharedInstance] newManagedObjectContext];

    [self loadRecordsFromCoreData];

    [self loadRecordsFromCoreDataForTourDetail];

    NSLog(@"Tour Detail array count: %d", [self.toursTest count]);

    // Do any additional setup after loading the view.
}

- (void)loadRecordsFromCoreData {
    [self.managedObjectContext performBlockAndWait:^{
        [self.managedObjectContext reset];
        NSError *error = nil;
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([Tour class])];
        [request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES]]];
        self.tours = [self.managedObjectContext executeFetchRequest:request error:&error];
    }];
}

更新:

问题的根源肯定来自我为 Fetched 属性定义的谓词,但您能否建议我应该如何编写谓词以链接两个表。当我编写谓词 tour_id == 0 并直接引用我知道存在的 id 时,获取的属性可以正常工作。但是当我使用 $FETCH_SOURCE.id 时,会引发键值编码异常。您使用什么属性来引用您希望链接到的表?

非常感谢您对此提供的所有帮助。

谢谢,迈克尔

4

5 回答 5

0

@property (nonatomic, 保留) NSNumber * id;

Objective-C中不是id保留字吗?您是否尝试过将此属性重命名为其他名称,以查看是否会导致任何冲突?

于 2013-02-08T10:00:45.767 回答
0

在没有看到您的代码的情况下,您正在调用 iOS6 中已弃用的类的方法,因此崩溃。

于 2013-02-07T19:30:20.497 回答
0

您发布的代码中没有viewWillAppear任何内容以任何明显的方式触及核心数据,这使得很难猜测发生了什么。其中一些对象可能是托管对象,但谁知道哪些对象或您是如何创建它们的?

但是,错误消息确实提供了一个巨大的线索:

[<_NSObjectID_48_0 0xb63e310> valueForUndefinedKey:]: this class is not key value coding-compliant for the key id.

这提到的事实_NSObjectID_48_0表明,在某些时候您正在使用NSManagedObjectID实例,而您期望NSManagedObject实例。NSManagedObjectID没有一个名为 的属性id,无论实体是什么样的,所以询问它id会产生“不符合键值编码”的错误。

至于为什么会发生这种情况,仍然无法说,因为您还没有发布任何代码来提供有关您如何使用 Core Data 的任何线索。

可能与谓词有关:

tour_id == $FETCH_SOURCE.id

如果您构造了一个 fetch ,那么它$FETCH_SOURCE就是一个NSManagedObjectID,这将是一个问题。也许(我只能猜测)您在请求结果类型时使用它NSManagedObjectIDResultType

于 2013-02-07T22:18:21.113 回答
0

无需深入研究您的代码,NSFetchRequest 可以设置返回的结果类型,例如,NSManagedObject ID ResultType 或 NSManagedObjectResultType。

需要 NSManagedObjectResultType,但会返回 NSManagedObjectIDResultType。

于 2015-02-08T16:48:48.923 回答
0

我在使用 MagicalRecord 时遇到了同样的问题,但在使用 Xcode 生成 CoreData 源代码时没有问题。

于 2016-09-20T02:26:10.747 回答