什么时候在NSManagedObject上调用initWithCoder?

时间:2014-05-06 04:49:39

标签: ios objective-c core-data nsmanagedobject

我在核心数据中有一对多的关系,其中RecipeStep有一对多的关系。

当我尝试获取已保存的食谱时,我遇到了这个崩溃:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Step initWithCoder:]: unrecognized selector sent to instance 0x9b30a20'

这是获取食谱的代码:

//Create the fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];

//Here is the entity whose contents we want to read
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:self.managedObjectContext];

//Tell the request that we want to read the contents of the Recipe entity
[fetchRequest setEntity:entity];

NSError *requestError = nil;
//Execute the fetch request on the context
self.recipes = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError];

只有在我拿取食谱时才会崩溃,而不是在我创建和保存时崩溃。

这是Step.h:

@class Recipe;

@interface Step : NSManagedObject

@property (nonatomic, retain) id photo;
@property (nonatomic, retain) NSString * instruction;
@property (nonatomic, retain) id timer;
@property (nonatomic, retain) Recipe *recipe;

@end

Step.m:

@implementation Step

@dynamic photo;
@dynamic instruction;
@dynamic timer;
@dynamic recipe;

Recipe.h:

@class Step;

@interface Recipe : NSManagedObject

@property (nonatomic, retain) id image;
@property (nonatomic, retain) id ingredients;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSOrderedSet *steps;

- (void) addIngredient: (NSString *) ingredient;
- (void) addIngredients:(NSArray *)ingredients;
- (BOOL) saveRecipe;

@end

@interface Recipe (CoreDataGeneratedAccessors)

- (void)insertObject:(Step *)value inStepsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromStepsAtIndex:(NSUInteger)idx;
- (void)insertSteps:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeStepsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInStepsAtIndex:(NSUInteger)idx withObject:(Step *)value;
- (void)replaceStepsAtIndexes:(NSIndexSet *)indexes withSteps:(NSArray *)values;
- (void)addStepsObject:(Step *)value;
- (void)removeStepsObject:(Step *)value;
- (void)addSteps:(NSOrderedSet *)values;
- (void)removeSteps:(NSOrderedSet *)values;

@end

Recipe.m:

@implementation Recipe

@dynamic image;
@dynamic ingredients;
@dynamic title;
@dynamic steps;

- (void) addSteps:(NSOrderedSet *)values
{
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.steps];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    NSUInteger valuesCount = [values count];
    NSUInteger objectsCount = [tmpOrderedSet count];
    for (NSUInteger i = 0; i < valuesCount; ++i) {
        [indexes addIndex:(objectsCount + i)];
    }
    if (valuesCount > 0) {
        [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"Step"];
        [tmpOrderedSet addObjectsFromArray:[values array]];
        [self setPrimitiveValue:tmpOrderedSet forKey:@"Step"];
        [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"Step"];
    }
}

我是否需要在initWithCoder:中实施Step?如果是,我在该方法中需要做什么?它为什么以及何时被称为?

修改:当我没有设置image的{​​{1}}属性时,没有崩溃。我不知道它与Recipe有什么关系。我将Step的图像设置为:

Recipe

这可以保存配方。只有当我抓取时,应用程序才会崩溃。看起来UIImage *squareImage = [self imageCrop:theImage]; recipe.image = squareImage; 在某处与image混在一起。此外,我尝试在Step中实施initWithCoder,然后在我尝试对图片执行某些操作时又发生了一次崩溃:

Step

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

归档自定义对象时会调用它。这个link可以帮助您理解

在上面的代码中,您在“Step”中有自定义对象类型“Recipe”。这个answer会帮助您

您的食谱类应如下所示进行存档,即使用数据类型的键值对进行通信。

这些方法是归档过程和取消归档过程的一部分。

-(id)initWithCoder:(NSCoder *)aDecoder
{
//read
if(self = [super init]){
    property1=[aDecoder decodeObjectForKey:@"property1"];
}
return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder
{
//save
[encoder encodeObject:property1 forKey:@"property1"];
}

答案 1 :(得分:0)

问题是其中一种方法中的拼写错误,并且由于内存损坏而发生崩溃。崩溃日志显示与拼写错误无关!

在Recipe.m的addSteps:方法中,我使用了班级名称Step而不是属性名称steps

应该是这样的:

[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"steps"];
[tmpOrderedSet addObjectsFromArray:[values array]];
[self setPrimitiveValue:tmpOrderedSet forKey:@"steps"];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"steps"];

而不是:

[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"Step"];
[tmpOrderedSet addObjectsFromArray:[values array]];
[self setPrimitiveValue:tmpOrderedSet forKey:@"Step"];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:@"Step"];