我的应用程序的一部分基于 Apple 的 CoreDataRecipes 示例代码,可在
http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
经过一些修改后,我花了好几个小时追踪一个我必须引入的错误,但我通过删除苹果代码中存在的两行代码解决了这个问题。
我在 NSManagedDataObject 配方中添加了一个作者属性,在实现上相同 - 据我所知 - 到配方已经具有的其他字符串属性。我的新属性在进入和离开由 IngredientDetailViewController 控制的模态视图后变成了僵尸。IngredientDetailViewController 的 dealloc 方法是
- (void)dealloc {
[recipe release];
[ingredient release];
[super dealloc];
}
找到错误后,我注释掉了配方和成分(另一个 NSManagedObject)的版本,我的应用程序现在似乎正在运行。我现在发现我的代码在有或没有这些发布调用的情况下都可以工作;该错误必须已通过我所做的另一项更改修复。我现在想知道
- 为什么苹果的示例代码最初是这样写的?
- NSManagedObject 配方的原始属性是什么,这意味着它们不容易受到 dealloc 调用的僵尸化?
如果以上内容还不足以表明我的无知,我应该指出我是 Objective C 和 iPhone 开发的新手,但我真的很想了解这里发生了什么。
针对评论进行编辑并更新:
我现在无法通过取消注释这些行来复制僵尸创建,显然在错误排除期间的另一个更改起到了作用。我最初询问的一些内容现在无效,但这让我对 NSManagedObjects 的 release 使用更加困惑,因为现在无论是否有这些调用,功能似乎都相同。我现在的主要问题是他们是否应该在那里。保存在成分详细信息视图中时发生崩溃。这是标题:
@class Recipe, Ingredient, EditingTableViewCell;
@interface IngredientDetailViewController : UITableViewController {
@private
Recipe *recipe;
Ingredient *ingredient;
EditingTableViewCell *editingTableViewCell;
}
@property (nonatomic, retain) Recipe *recipe;
@property (nonatomic, retain) Ingredient *ingredient;
@property (nonatomic, assign) IBOutlet EditingTableViewCell *editingTableViewCell;
@end
和保存方法:
- (void)save:(id)sender {
NSManagedObjectContext *context = [recipe managedObjectContext];
/*
If there isn't an ingredient object, create and configure one.
*/
if (!ingredient) {
self.ingredient = [NSEntityDescription insertNewObjectForEntityForName:@"Ingredient"
inManagedObjectContext:context];
[recipe addIngredientsObject:ingredient];
ingredient.displayOrder = [NSNumber numberWithInteger:[recipe.ingredients count]];
}
/*
Update the ingredient from the values in the text fields.
*/
EditingTableViewCell *cell;
cell = (EditingTableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
ingredient.name = cell.textField.text;
cell = (EditingTableViewCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
ingredient.amount = cell.textField.text;
/*
Save the managed object context.
*/
NSError *error = nil;
if (![context save:&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.
If it is not possible to recover from the error, display an alert panel that instructs the user to quit the
application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.navigationController popViewControllerAnimated:YES];
NSLog(@"in ingredient detail save after ingredient pop; - recipe.author is %@", recipe.author);
}
由于我是新用户,数据模型的截图不能放在这里,所以这里有一个链接:数据模型截图
最后是配方标题:
@interface ImageToDataTransformer : NSValueTransformer {
}
@end
@interface Recipe : NSManagedObject {
}
@property (nonatomic, retain) NSString *instructions;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *overview;
@property (nonatomic, retain) NSString *prepTime;
@property (nonatomic, retain) NSSet *ingredients;
@property (nonatomic, retain) UIImage *thumbnailImage;
@property (nonatomic, retain) NSString *author;
@property (nonatomic) BOOL *isDownloaded;
@property (nonatomic) BOOL *isSubmitted;
@property (nonatomic, retain) NSString *uniqueID;
@property (nonatomic) float averageRating;
@property (nonatomic) float numberOfRatings;
@property (nonatomic, retain) NSManagedObject *image;
@property (nonatomic, retain) NSManagedObject *type;
@end
@interface Recipe (CoreDataGeneratedAccessors)
- (void)addIngredientsObject:(NSManagedObject *)value;
- (void)removeIngredientsObject:(NSManagedObject *)value;
- (void)addIngredients:(NSSet *)value;
- (void)removeIngredients:(NSSet *)value;
@end
再次感谢。