У меня есть tableViewController, поддерживаемый fetchedResultsController / UIManagedDocument, который использует данные, полученные с сервера с помощью сообщений JSON.Он создан по образцу ТВЦ, использованного в лекциях по программированию iPhone в Стэнфорде 2011 года.Программа загружается, обновляется с сервера и безупречно обновляет tableView.Однако, когда я пытаюсь редактировать информацию в ячейке, у меня получается очень странный результат.
Я редактирую объекты в классе PlugDetailTVC, который сообщает классу DataFetcher для отправки соответствующего сообщения JSON.Затем вся база данных перезагружается через getAllPlugsInDocument.Все отлично работаетправильный JSON отправлен и правильный ответ получен.База данных сервера обновляется правильно.после запуска getAllPlugsInDocument tableView отображает правильную обновленную информацию.Затем через 10-15 секунд программа выдает исключение без сообщения об ошибке!
UPDate: я внес одно изменение в свой код, которое было изменением saveToURL.document.fileURL на
[self.document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting
completionHandler:^(BOOL success) {
if (success) {
NSLog(@"PlugFetcher Document saved");
} else {
NSLog(@"PlugFetcher Document was unable to save");
}
НО!Я дал код кому-то еще для запуска (симулятор xcode 4.2 / iPhone 5.1 с хаком для запуска iOS 5.1) Он работал отлично!Затем я запустил его на своем телефоне - 4S с iOS 5.1 Снова работает отлично.Вернуться к симулятору iPhone 5.1 на xCode 4.3.1 - тот же старый сбой, даже после сброса содержимого, настроек и т. Д. Теперь я более озадачен, чем раньше.
Соответствующий код:
PlugsTableViewController
-(void)setupFetchedResultsController{
NSManagedObjectContext *context=self.mainDatabase.managedObjectContext;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Plug"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]];
self.fetchedResultsController= [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
}
-(void)fetchPlugDataIntoDocument:(UIManagedDocument *)document{
NSLog(@"fetchPlugDataIntoDocument");
PlugFetcher *plugFetcher=[PlugFetcher getInstance];
[plugFetcher getAllTimeZones:document];
[plugFetcher getAllPlugsInDocument:document];
}
//Open or create document,call setupFetchedResultsController
-(void)useDocument{
if (![[NSFileManager defaultManager]fileExistsAtPath:[self.mainDatabase.fileURL path]]) {
NSLog(@"######## Document Does not exist #########");
[self.mainDatabase saveToURL:self.mainDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
}else if (self.mainDatabase.documentState==UIDocumentStateClosed){
NSLog(@"######## Document closed #########");
[self.mainDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
}else if (self.mainDatabase.documentState==UIDocumentStateNormal){
NSLog(@"######## Document Normal #########");
[self setupFetchedResultsController];
}
[self fetchPlugDataIntoDocument:self.mainDatabase];
}
-(void)setmainDatabase:(UIManagedDocument *)mainDatabase{
if (_mainDatabase!=mainDatabase) {
_mainDatabase=mainDatabase;
[self useDocument];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.mainDatabase) {
NSLog(@"######## !self.mainDatabase #########");
NSURL *url=[[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]lastObject];
url=[url URLByAppendingPathComponent:@"main Database"];
self.mainDatabase=[[UIManagedDocument alloc]initWithFileURL:url];
PlugFetcher *plugFetcher=[PlugFetcher getInstance];
plugFetcher.context=self.mainDatabase.managedObjectContext;
plugFetcher.document=self.mainDatabase;
}
}
PlugFetcher.m
- (void)getAllPlugsInDocument:(UIManagedDocument*)document{
NSManagedObjectContext *context=[document managedObjectContext];
dispatch_queue_t fetchQ=dispatch_queue_create("Data Fetcher", NULL);
dispatch_async(fetchQ, ^{
NSDictionary *serverDictionary=[self.serverCommManager getServerPlugList];
if([[serverDictionary objectForKey:@"success"] isEqualToString:@"true"]){
NSArray *serverPlugArray=[serverDictionary objectForKey:@"response"];
[document.managedObjectContext performBlock:^{ // perform in the NSMOC's safe thread (main thread)
NSEntityDescription *plugEntity = [NSEntityDescription entityForName:@"Plug" inManagedObjectContext:context];
[self deleteAllObjectsInEntity:plugEntity forPlug:nil inContext:context];
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"TimeZone"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"utcOffset"
ascending:YES]];
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterNoStyle];
for (NSDictionary *plugFromServer in serverPlugArray){
Plug *newLocalPlug=[NSEntityDescription insertNewObjectForEntityForName:@"Plug" inManagedObjectContext:context];
newLocalPlug.plugID = [plugFromServer valueForKey:@"id"];
newLocalPlug.name = [plugFromServer valueForKey:@"name"];
newLocalPlug.location = [plugFromServer valueForKey:@"loc"];
newLocalPlug.notes = [plugFromServer valueForKey:@"notes"];
newLocalPlug.state=[plugFromServer valueForKey:@"state"];
}
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
}];
}else{
NSLog(@"PLUGFETCHER getAllPlugs:json response=fail");
}
});
}
-(void)updatePlug:(Plug*)plug{
NSString *json = [JSONQuery queryUpdateDevice:plug.plugID
name:plug.name
location:plug.location
notes:plug.notes
dummy:plug.dummy
state:plug.state
timezone:[NSString stringWithFormat:@"%@", plug.timeZone.utcOffset]];
[self.serverCommManager send:json];
}
PlugDetailTVC:
if ([[segue identifier] isEqualToString:@"savePlugDetail"]){
//forces saving of info in field be edited when button is pushed
[self.view.window endEditing: YES];
[self.currentTextField endEditing:YES];
NSLog(@"PlugDetailTVC prepareForSeque plug:%@",self.plug.plugID);
PlugFetcher *plugFetcher= [PlugFetcher getInstance];
[plugFetcher updatePlug:self.plug];
}