0

我有一个常见的应用程序模式:用户在主视图控制器中输入数据,然后在模态视图控制器的表中查看它,其中可以删除或修改行。我遵循斯坦福 iPhone 课程的一般设计策略,但在某处事情出轨了,我得到的只是 SIGABRT 和例外情况,例如“非法尝试在不同上下文中的对象之间建立关系 'xyz'”。

在斯坦福课程中,我使用了一个名为“Database”的单例类,它应该在请求时返回相同的上下文。所以我在主视图控制器上的 viewDidLoad 方法中的第一个命令是:

 dbsingleton = [Database sharedInstance];
 nmocontext = [dbsingleton managedObjectContext];

nmocontext 是我在整个视图控制器中使用的一个 ivar。当用户想要查看另一个视图控制器时,我会分配初始化它,然后以模态方式呈现它。(它有一个 NSFetchedResultsController 从我的商店提供数据。)我在这里尝试了各种策略:

  • 我已将 NSFetchedResultsController 设置为由主视图控制器设置的保留属性
  • 我已将 NSManagedObjectContext 设为主视图控制器设置的保留属性;和
  • 通过在表格视图控制器的 viewDidLoad 方法的开头重复上面的这两行代码,我在内部使用了单例。

无论我选择哪一个,我无法解决的一个问题是,在用户关闭并释放表视图控制器(及其 NSFetchedResultsController)后,当访问存储时,我开始在主视图控制器中崩溃(如“上面提到的非法尝试”错误)。

处理这种常见应用程序模式的最佳实践是什么?我仍然希望使这个应用程序与 iPhone SDK 3.x 兼容,但是当我使用 iOS 4 时,我的崩溃似乎确实更少——如果 3.x 存在导致我出现问题的潜在问题,请告诉我知道,我可能只针对 iOS 4。

谢谢!

4

2 回答 2

0

这只是一个猜测,但我认为关闭 tableview 后崩溃会出现以下问题:

你声明了一个属性

@property (retain, nonatomic) NSManagedObjectContext* nmocontext;

你在 dealloc 中正确释放 ivar nmocontext 吗?如果是,你的问题是作业

nmocontext = [dbsingleton managedObjectContext];

这永远不会在您的视图控制器中保留 nmocontext,但您会在 dealloc 上释放它。

第二:

“非法尝试在不同上下文中的对象之间建立关系‘xyz’。”

这不是内存管理问题,但您可能创建了另一个新上下文来添加对象(如在苹果核心数据 iphone 示例中)并尝试将 NSManagedObject 设置为来自不同上下文的关系。

于 2010-09-12T05:40:09.700 回答
0

听起来您没有正确配置单例。

单例应该重写release以不做任何事情,以便在发送释放消息时什么都不会发生。如果您不覆盖release,那么应用程序中任何地方的任何随机代码都可以杀死单例并破坏使用单例的全部目的。下次你调用单例时,你实际上得到了另一个新对象,在这种情况下它也返回一个新的托管对象上下文。

请参阅Cocoa 基础指南:创建单例实例

单例功能强大且灵活,但很容易出错。它们很容易搞砸,以至于许多有经验的开发人员干脆拒绝使用它们。如果没有使用它们的经验,请不要在刚开始时使用它们。

于 2010-09-14T13:23:33.343 回答