停止应用程序后核心数据关系不起作用

发布于 2024-12-20 08:01:49 字数 3699 浏览 2 评论 0原文

我在核心数据和关系方面遇到了一个问题。由于这让我有一段时间没有解决方案,同时又很容易找到,我制作了一个小型示例应用程序来重现该问题。 在 XCode 下,我创建了一个基于 Window 的准系统应用程序,选中“使用核心数据进行存储”。 我将此应用程序称为“CDR”,代表核心数据关系。 然后我添加了一个名为 CDR_ViewController 的 UIViewController 子类;就像我通常做的那样。 这是我添加的相关代码: 首先在CDR_ViewController.h中:

#import <UIKit/UIKit.h>
#import "AppDelegate_Shared.h"

@interface CDR_ViewController : UIViewController {
UILabel *cdrLabel;
NSManagedObject *currentItem;
}

@property (nonatomic, retain) IBOutlet UILabel *cdrLabel;

-(IBAction) handleButtonClick:(id)sender;

@end

然后在CDR_ViewController.m中,viewDidLoad方法如下:

- (void)viewDidLoad {
[super viewDidLoad];

NSFetchRequest *request;
NSError *error;

AppDelegate_Shared *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];

request=[[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];

error=nil;
NSUInteger count = [context countForFetchRequest:request error:&error];
[request release];
if (count!=0) {
    request=[[NSFetchRequest alloc] init];
    [request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];
    error=nil;
    NSArray *objects=[context executeFetchRequest:request error:&error];
    NSLog(@"Error:%@",error);
    [request release];
    currentItem=[objects objectAtIndex:0];
    return;
}

NSManagedObject *newItemOne,*newItemTwo,*newItemThree;

request=[[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];

newItemOne=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];
newItemTwo=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];
newItemThree=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];

[newItemOne setValue:[NSNumber numberWithInteger:1] forKey:@"Value"];
[newItemTwo setValue:[NSNumber numberWithInteger:2] forKey:@"Value"];
[newItemThree setValue:[NSNumber numberWithInteger:3] forKey:@"Value"];

[newItemOne setValue:newItemThree forKey:@"Previous"];
[newItemOne setValue:newItemTwo forKey:@"Next"];
[newItemTwo setValue:newItemOne forKey:@"Previous"];
[newItemTwo setValue:newItemThree forKey:@"Next"];
[newItemThree setValue:newItemTwo forKey:@"Previous"];
[newItemThree setValue:newItemOne forKey:@"Next"];

error=nil;
[context save:&error];
[request release];
currentItem=newItemOne;
}

viewWillAppear方法如下:

- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
cdrLabel.text=[NSString stringWithFormat:@"%@",[currentItem valueForKey:@"Value"]];
}

最后handleButtonClick方法如下:

-(IBAction) handleButtonClick:(id)sender
{
if (((UIButton*)sender).tag==101) {// Previous item.
    currentItem=[currentItem valueForKey:@"Previous"];
} else /*(((UIButton*)sender).tag==102)*/ {// Next item.
    currentItem=[currentItem valueForKey:@"Next"];
}
cdrLabel.text=[NSString stringWithFormat:@"%@",[currentItem valueForKey:@"Value"]];
}

CDR_ViewController.xib包含一个Label和两个按钮。

这段代码在启动时工作得很好,这意味着在我编译应用程序并重置 iPhone 模拟器的内容之后。 然后我可以循环标签的内容:1,2,3,1,2,3,1,2,3 ---等等...并使用按钮向后。 一旦我使用 Command-Q 终止应用程序。当我想再次启动它时,它

currentItem=[currentItem valueForKey:@"Previous"];

:或:

currentItem=[currentItem valueForKey:@"Next"];

在handleButtonClick 方法内的 处崩溃。 当我将应用程序安装到 iPod touch 上时也是如此。

任何人都可以在我的代码中看到任何可以解释这种行为的内容吗?

I have had one issue with Core Data and Relationship. Since this has kept me without a solution for a while and has at the same time been easy to locate I have made a tiny sample application to reproduce the problem.
Under XCode I created a barebone Window-based application, checking "Use Core Data for storage".
I called this application "CDR" for Core-Data-Relationship.
I then added a subclass of UIViewController called CDR_ViewController; as I usually do.
Here is the relevant code that I added :
First in CDR_ViewController.h :

#import <UIKit/UIKit.h>
#import "AppDelegate_Shared.h"

@interface CDR_ViewController : UIViewController {
UILabel *cdrLabel;
NSManagedObject *currentItem;
}

@property (nonatomic, retain) IBOutlet UILabel *cdrLabel;

-(IBAction) handleButtonClick:(id)sender;

@end

Then in CDR_ViewController.m the viewDidLoad method is as follow :

- (void)viewDidLoad {
[super viewDidLoad];

NSFetchRequest *request;
NSError *error;

AppDelegate_Shared *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];

request=[[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];

error=nil;
NSUInteger count = [context countForFetchRequest:request error:&error];
[request release];
if (count!=0) {
    request=[[NSFetchRequest alloc] init];
    [request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];
    error=nil;
    NSArray *objects=[context executeFetchRequest:request error:&error];
    NSLog(@"Error:%@",error);
    [request release];
    currentItem=[objects objectAtIndex:0];
    return;
}

NSManagedObject *newItemOne,*newItemTwo,*newItemThree;

request=[[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"CDR_Entity" inManagedObjectContext:context]];

newItemOne=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];
newItemTwo=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];
newItemThree=[NSEntityDescription insertNewObjectForEntityForName:@"CDR_Entity" inManagedObjectContext:context];

[newItemOne setValue:[NSNumber numberWithInteger:1] forKey:@"Value"];
[newItemTwo setValue:[NSNumber numberWithInteger:2] forKey:@"Value"];
[newItemThree setValue:[NSNumber numberWithInteger:3] forKey:@"Value"];

[newItemOne setValue:newItemThree forKey:@"Previous"];
[newItemOne setValue:newItemTwo forKey:@"Next"];
[newItemTwo setValue:newItemOne forKey:@"Previous"];
[newItemTwo setValue:newItemThree forKey:@"Next"];
[newItemThree setValue:newItemTwo forKey:@"Previous"];
[newItemThree setValue:newItemOne forKey:@"Next"];

error=nil;
[context save:&error];
[request release];
currentItem=newItemOne;
}

And the viewWillAppear method is as follow :

- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
cdrLabel.text=[NSString stringWithFormat:@"%@",[currentItem valueForKey:@"Value"]];
}

Finally the handleButtonClick method is as follow :

-(IBAction) handleButtonClick:(id)sender
{
if (((UIButton*)sender).tag==101) {// Previous item.
    currentItem=[currentItem valueForKey:@"Previous"];
} else /*(((UIButton*)sender).tag==102)*/ {// Next item.
    currentItem=[currentItem valueForKey:@"Next"];
}
cdrLabel.text=[NSString stringWithFormat:@"%@",[currentItem valueForKey:@"Value"]];
}

The CDR_ViewController.xib contains one Label and two buttons.

This code works fine for start, meaning just after I compile the app and reset the contents of the iPhone simulator.
I can then cycle the contents of the label : 1,2,3,1,2,3,1,2,3 ---etc… and backward with the buttons.
As soon as I terminate the application using Command-Q. When I want to start it again, it crashes on :

currentItem=[currentItem valueForKey:@"Previous"];

or:

currentItem=[currentItem valueForKey:@"Next"];

inside the handleButtonClick method.
And it is the same when I put the app on my iPod touch.

Can anyone see in my code anything that could explain this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诠释孤独 2024-12-27 08:01:49

如果您通过停止模拟器中的应用程序(而不是单击模拟器中的主页按钮或其他方式)来终止应用程序,则会向程序发送一条 SIGKILL 消息,立即停止其运行。您的应用程序委托方法(将终止、将进入后台等)将不会被调用。

这很可能意味着您的托管对象上下文尚未保存,因此重新运行应用程序时,对象图无法正确恢复。在您的示例应用程序中,添加另一个保存上下文的按钮。如果您单击此按钮,然后终止您的应用程序,是否可以解决问题?

If you terminate an app in the simulator by stopping it, a opposed to clicking the home button in the simulator or otherwise, then the program is sent a SIGKILL message which immediately stop it running. Your application delegate methods (will terminate, will enter background etc) will not be called.

In all likelihood this will have meant that your managed object context has not been saved, so when re-running the app the object graph cannot be restored properly. In your sample app, add another button which saves the context. If you click this button, then terminate your app, does that solve the problem?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文