2013-03-01 66 views
0

我在(核心數據)實體中保存了我的tableviewdata的最新互聯網請求,但在關於「錯誤」的錯誤例外方面存在問題。 我有兩個方法'loadData'獲取最新的'ordersitems'將被加載在我的tableview和'loadThumbnails',它會嘗試緩存縮略圖到核心數據實體。 當managedobject被刪除並且縮略圖方法仍嘗試訪問它時,會發生此問題。雖然我做了一個變量stopThumbnails來停止loadThumbnails方法,但問題仍在繼續。在IOS6中使用核心數據(刪除/編輯)

什麼是適當的iOS 6方式來延遲加載圖像並將它們保存到coredata,但檢查對象是否沒有被刪除?我發現這Core Data multi thread application這是有用的,但我對核心數據的新手理解仍然有限,我有問題編寫代碼。我讀了關於http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html的蘋果文檔,但很難完全理解。

我想至少我的http請求加載臺異步(但最好儘可能地)我想出了以下內容:

-(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以來,可以使用塊代替爲您合併。所以我決定用這個來代替派遣的方式(這種方式我不必使用notofications)。

同樣使用塊我得到同樣的問題(故障),當一個對象在背景隊列上被選中時,在另一個隊列上被刪除。所以我決定不是馬上刪除它,而是爲OrderItem插入一個NSDate'deleted'屬性。然後有一個帶有刪除檢查的計時器,以查看是否有超過10分鐘前已刪除的對象。這樣我確信沒有縮略圖還在下載。有用。雖然我仍然想知道身份證這是正確的方法:)