Исключение iOS5 UIManagedDocument и FetchedResultsController, при сохранении изменений - PullRequest
2 голосов
/ 15 марта 2012

У меня есть 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];
}
...