2013-03-01 3 views
0

Я сохраняю последний интернет-запрос своих табличных данных в объекте (основных данных), но имею проблемы с исключениями ошибок в отношении «сбоев». У меня есть два метода loadData, которые получают последние «orderitems», которые будут загружены в моем табличном представлении AND «loadThumbnails», который попытается кэшировать миниатюру в основной объект данных. Проблема возникает, когда удаленный объект удаляется, и метод эскизов по-прежнему пытается получить к нему доступ. Хотя я сделал переменную stopThumbnails, чтобы остановить метод loadThumbnails, проблема продолжает возникать.Использование основных данных в IOS6 (удаление/редактирование)

Какова правильная версия iOS 6 для lazyload изображений и сохранения их в coredata, но проверьте, не был ли объект удален? Я нашел это Core Data multi thread application, который был полезен, но мой новичок понимание основных данных по-прежнему ограничен, и у меня проблемы с написанием кода. Я прочитал документы яблока о http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html, но это было трудно понять полностью.

Я хочу, чтобы по крайней мере мой запрос HTTP для загрузки asychronous (но желательно как можно больше) я придумал следующее:

-(void)viewdidload 
{ 
    NSFetchRequest *fetchReq = [NSFetchRequest fetchRequestWithEntityName:@"OrderItems"]; 
    fetchReq.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];      
    self.data = [self.managedObjectContext executeFetchRequest:fetchReq error:nil]; 

    MYFILTER = @"filter=companyX"; 

    [self loadData]; 
} 

-(void)loadData 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     //json request from url 
     NSDictionary *reqData = myOrderJSONRequest(MYFILTER); 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      if(reqData!=NULL && reqData!=nil) 
      { 
       //request successful so delete all items from entity before inserting new ones 

       stopThumbnails = YES; 
       for(int i=self.data.count-1;i>=0;i--) 
       { 
        [self.managedObjectContext deleteObject:[self.data objectAtIndex:i]]; 
       } 
       [self.managedObjectContext save:nil]; 

       if(reqData.count>0) 
       { 
        //insert latest updates   
        for (NSDictionary *row in reqData){ 
         OrderItem *item = [NSEntityDescription insertNewObjectForEntityForName:@"OrderItem" inManagedObjectContext:self.managedObjectContext]; 
         item.order_id = [NSNumber numberWithInt:[[row objectForKey:@"order_id"] intValue]]; 
         item.description = [row objectForKey:@"description"]; 
         item.thumbnail_url = [row objectForKey:@"thumbnail_url"]; 
        } 
        [self.managedObjectContext save:nil]; 
       } 

       NSFetchRequest *fetchReq = [NSFetchRequest fetchRequestWithEntityName:@"OrderItems"]; 
       fetchReq.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];      
       self.data = [self.managedObjectContext executeFetchRequest:fetchReq error:nil];      

       [TableView reloadData]; 

       //LOAD THUMBNAILS ASYNCHRONOUS 
       stopThumbnails = NO; 
       [self loadThumbnails];      
      } 
      else{ 
       //NO INTERNET 
      } 
     }); 
    }); 
} 

-(void)loadThumbnails 
{ 
if(!loadingThumbnails) 
{ 
    loadingThumbnails = YES; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     for (int i=0;i<self.data.count; i++) { 
      if(!stopThumbnails) 
      { 
       OrderItem *item = [self.data objectAtIndex:i]; 
       if(item.thumbnail==NULL) 
       { 
        //ASYNCHRONOUS IMAGE REQUEST 
        NSURL *image_url = [NSURL URLWithString:item.thumbnail_url]; 
        NSData *image_data = [NSData dataWithContentsOfURL:image_url]; 

        dispatch_async(dispatch_get_main_queue(), ^{ 
         if(image_data!=nil && image_data!=NULL && !stopThumbnails) 
         { 
          //IMAGE REQUEST SUCCESSFUL 
          item.thumbnail = image_data; 
          [self.managedObjectContext save:nil]; 

          //RELOAD AFFECTED TABLEVIEWCELL 
          NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:i inSection:0]; 
          NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil]; 
          [TableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationFade]; 
         } 
         else 
         { 
          loadingThumbnails = NO; 
          return; 
         } 
        }); 
       } 

       if(stopThumbnails) 
       { 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         loadingThumbnails = NO; 
         return; 
        }); 
       } 
      } 
      else{ 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        loadingThumbnails = NO; 
        return; 
       }); 
      } 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      loadingThumbnails = NO; 
      return; 
     }); 
    }); 
} 
} 

Любая помощь, конечно, очень ценится :)

ответ

0

Ну Я не знаю, подходит ли это подход, но он работает, поэтому я буду отмечать это как ответ.

Чтобы сделать все на фоне, я использовал второй nsmanagedobjectcontext (MOC), а затем объединил изменения в основной MOC. очередь отправки работает отлично, хотя мне пришлось использовать NSManagedObjectContextDidSaveNotification, чтобы объединить изменения двух контекстов.

с IOS 5 его можно использовать вместо блоков, которые делают слияние для вас. Поэтому я решил использовать это вместо пути отправки (таким образом, я не должен был использовать недостоверности).

Также, используя блоки, я получил ту же проблему (ошибки), когда объект, выбранный в фоновом режиме, был удален в другой очереди. Поэтому я решил вместо удаления сразу вставить свойство NSDate 'deleted' для OrderItem. затем установите таймер с проверкой удаления, чтобы увидеть, есть ли объекты, которые были удалены более 10 минут назад. Таким образом, я уверен, что эскиз еще не загружался. Оно работает. Хотя я все равно хотел бы знать, что это правильный подход :)

Смежные вопросы