2010-09-12 48 views
6

偶尔阅读器和第一次的问题提问者,所以请温柔:)过度释放引起的奇数核心数据错误?

我创建一个管理对象(账户),正在传递到哪里它在这是一个属性被设置子视图控制器保留。

Account * account = [[Account alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; 
AddAccountViewController *childController = [[AddAccountViewController alloc] init]; 
childController.title = @"Account Details"; 
childController.anAccount = account; 
childController.delegate = self; 

[self.navigationController pushViewController:childController animated:YES]; 
[childController release]; 
[account release]; 

视图控制器接口:

@interface AddAccountViewController : UIViewController { 
} 

@property (nonatomic, retain) IBOutlet UITextField * usernameTextField; 
@property (nonatomic, retain) IBOutlet UITextField * passwordTextField; 

@property (nonatomic, retain) Account * anAccount; 
@property (nonatomic, assign) id <AddAccountDelegate> delegate; 

- (IBAction)cancel:(id)sender; 
- (IBAction)add:(id)sender; 
- (IBAction)textFieldDone:(id)sender; 
@end 

所以代码示例1在我发布的帐户对象,因为我在那个方法已经不再感兴趣。由于它保留AddAccountViewController我有一个条目AddAccountViewControllerdealloc它释放它。

但是当我去从ManagedObjectContext以下的(不清楚)错误删除的对象应用程序崩溃:

Detected an attempt to call a symbol in system libraries that is not present on the iPhone: 
_Unwind_Resume called from function _PFFaultHandlerLookupRow in image CoreData. 

经过多番调试&头发拉我发现,如果我不AddAccountViewControllerdealloc方法该应用程序正常工作,并不会泄漏根据仪器。

任何人都可以说明发生了什么?我从文档中了解到那些保留的内容需要发布。我错过了什么?

更新回答凯文的问题

的代码从ManagedObjectContext删除的对象是在RootViewController的(即抱着小孩控制器)

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the managed object for the given index path 
     NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 

     [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

     // Save the 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(); 
     } 
    } 
} 
+0

可以显示从NSManagedObjectContext中删除它的代码吗?这是否发生在AddAccountViewController或其他地方? – 2010-09-12 09:53:47

+0

'childController.anAccount = account;'此行不保留'account'。它将它复制到'anAccount'。这根本不+1 +1它的保留,你只需要在'AddAccountViewcontroller'的dealloc方法中释放'anAccount'。 – 2010-09-12 10:07:16

+0

@Thomas:'@property(nonatomic,retain)Account * anAccount;'为什么不保留? – Pyetras 2010-09-12 10:17:06

回答

1

首先:这听起来就像苹果公司的一个错误。核心数据呼叫_Unwind_Resume,这可能是(某种)例外情况。在手机上存在异常展开,但(我认为)使用ARM ABI,它使用以__cxa_开头的函数名称。你在模拟器上运行吗?哪个版本的SDK?

当您删除对[account release];的呼叫时,可能会有额外的版本在某处“浮动”。 “工具不显示任何泄漏”并不意味着没有任何泄漏;最后我检查了它被周期弄糊涂了(即,如果你忘记在dealloc中取消设置IBOutlets,它不会显示泄漏)。我用NSMutableData * d = [NSMutableData dataWithLength:1<<20]; memcpy(d.mutableBytes, &d, 4);进行了测试,但更简单的测试只是[[UIView alloc] initWithFrame:CGRectZero]

如果您认为这是一个保留/发布问题,我曾经通过覆盖retain/release/autorelease来调试这些以调用NSLog。然后我添加了所有这些断点,并将它们设置为运行命令“bt”,然后单击autocontinue。然后运行中断事件(在我的情况下,我认为这只是一个额外的保留),打印日志输出,将其粘贴在白板上,并花费半个小时匹配保留和释放。

+1

事实上,在第一个块的末尾删除'[account release];'意味着'AddAccountViewController'中的'retain'&'release'得到了适当的平衡,并且在从' ManagedObjectContext'。关于第一部分,我在模拟器和设备上运行代码并获取该错误。 SDK是4.1GM。 – tarasis 2010-09-13 20:32:30

+0

如果删除'[account release];'如上所述修复它,则AddAccountViewController被破坏(相对于Obj-C内存管理约定)。如果不查看AddAccountViewController中的所有接触anAccount属性或其支持实例变量的代码,就很难找出它的破裂位置。 (另外,带有“a”或“an”的前缀属性/ ivars不在我知道的任何编码约定中,并且与Apple使用它的地方相矛盾。) – 2011-04-05 21:56:56

0

当您删除任何managed对象时,系统将自动释放与该对象相关的所有引用。所以没有必要以编程方式对对象进行修订。一旦你删除了对象,你就无法在父类中访问该对象。

+1

这是不正确的。当一个被管理的对象被删除时,它被标记为删除,但它不能释放内存,因为它违反了苹果的内存管理策略。 – 2010-10-06 04:47:03

+0

我研究了NSManagedObjectContext类,我发现当调用deleteObject方法时,对象将从uniquing表中删除。 – 2010-10-06 07:50:23

1

我有一个类似的问题在 结束“检测到系统尝试调用系统库一个符号,不存在对iPhone:从图像CoreData功能_PFFaultHandlerLookupRow称为 _Unwind_Resume。” 错误消息。

我的问题是模型中的关系错误的“级联”删除规则。有了这条规则,我的顶级托管对象被删除了,但仍在代码中引用。 将此关系的“删除规则”设置为“消除”后,所有内容都按设计工作。

- >没有核心数据问题...设计问题!

Johnny