Core-Data Relashionship не работает после остановки приложения - PullRequest
0 голосов
/ 10 декабря 2011

У меня была одна проблема с основными данными и отношениями.Поскольку это некоторое время оставляло меня без решения, и в то же время его было легко найти, я сделал крошечный пример приложения для воспроизведения проблемы.Под XCode я создал голое приложение на основе Windows, отметив «Использовать базовые данные для хранения».Я назвал это приложение «CDR» для Core-Data-Relationship.Затем я добавил подкласс UIViewController под названием CDR_ViewController;как я обычно делаю.Вот соответствующий код, который я добавил: сначала в 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 содержит одну метку и две кнопки.

Этот код работает нормальнодля начала, то есть сразу после того, как я скомпилирую приложение и сброслю содержимое симулятора iPhone.Затем я могу циклически изменить содержимое метки: 1,2,3,1,2,3,1,2,3 --- и т. Д. И обратно кнопками.Как только я завершу приложение, используя Command-Q.Когда я хочу запустить его снова, он падает:

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

или:

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

внутри метода handleButtonClick.И то же самое, когда я помещаю приложение на свой iPod touch.

Может ли кто-нибудь увидеть в моем коде что-нибудь, что могло бы объяснить такое поведение?

1 Ответ

0 голосов
/ 10 декабря 2011

Если вы закрываете приложение в симуляторе, останавливая его, в отличие от нажатия кнопки «Домой» в симуляторе или иным образом, тогда программе отправляется сообщение SIGKILL, которое немедленно останавливает его работу.Методы делегатов вашего приложения (прекратят работу, войдут в фоновый режим и т. Д.) Не будут вызываться.

По всей вероятности, это будет означать, что контекст управляемого объекта не был сохранен, поэтому при повторном запуске приложения граф объекта не может быть восстановлен должным образом.В вашем примере приложения добавьте еще одну кнопку, которая сохраняет контекст.Если вы нажмете эту кнопку, а затем закроете свое приложение, это решит проблему?

...