2014-02-27 24 views
0

NSFetchedResultsController結果我有一個主UITableView程序與各小區點擊引出了另一個UITableView發作與被點擊的程序。如何從UITableView中清除Restkit

問題:每當我點擊一個程序單元格時,它會將最後一個程序中的劇集追加到劇集表格視圖控制器中。例如:假設節目A有劇集i,ii,然後點擊劇集A在屏幕上顯示i,ii,假設節目B有劇集iii,然後點擊劇集B顯示i,ii,iii而不是僅僅是iii

我的嘗試:我保證,我總是從頭開始,每次實例化EpisodesDataSource我點擊一個programcell,而我每一次我點擊節目單元格時破壞了NSFetchedResultsController實例。我還保證,我不是添加相同的響應描述符不止一次..我以前也用過

[NSFetchedResultsController deleteCacheWithName:@"Master"]; 

,每次我打電話fetchedResultsController ..但仍然沒有運氣..請參閱下面的實現細節。

ProgramsViewController

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    Controller *controller = [Controller getSingleton]; 

    MediaListViewController *episodesVC = 
    [controller.storyboard instantiateViewControllerWithIdentifier:@"NewsReportsViewController"]; 
    ProgramCell *programCell = (ProgramCell *)[tableView cellForRowAtIndexPath:indexPath]; 

    episodesVC.dataSource = [[EpisodesDataSource alloc] initWithProgramId:programCell.programId]; 

    [self.navigationController episodesVC animated:YES]; 
} 

EpisodesDataSource

@implementation EpisodesDataSource 

- (id)initWithProgramId:(NSNumber *)programId { 
    self = [self init]; 
    self.programId = programId; 
    self.parameters = @{@"pid": programId}; 
    self.predicate = @"episode"; 
    return self; 
} 

- (id)init { 
    self = [super init]; 
    self.entityName = @"Episodes"; 
    self.resourcePath = kEpisodesPath; 
    self.sortKey = @"episode_title"; 
    self.keyPath = @"EpisodesList.Episode"; 
    return self; 
} 

- (void)addResponseDescriptor { 

    Model *model = [Model getSingleton]; 
    NSArray *existingResponseDescriptors = [model.objectManager.responseDescriptors mapObjectsUsingBlock:^(RKResponseDescriptor *descriptor, NSUInteger idx){ 
     return [descriptor keyPath]; 
    }]; 

    if ([existingResponseDescriptors containsObject:self.keyPath]) { 
     NSLog(@"response descriptor %@ already exsits! return", self.keyPath); 
     return; 
    } 

    NSLog(@"adding response descriptor %@", self.keyPath); 
    RKEntityMapping *episodesEntityMapping = [RKEntityMapping mappingForEntityForName:self.entityName inManagedObjectStore:model.managedObjectStore]; 
    // left is http, right is dbase 
    [episodesEntityMapping addAttributeMappingsFromDictionary:@{@"programId.text":  @"episode_id", 
                   @"EpisodeTitle.text": @"episode_title", 
                   @"EpisodeImageUrl.text": @"episode_image_url", 
                   @"EpisodeNewsUrl.text": @"episode_news_url", 
                   @"EpisodeVideoUrl.text": @"episode_video_url", 
                   @"EpisodeVideoId.text": @"episode_video_id", 
                   @"EpisodeCaption.text": @"episode_caption", 
                   @"EpisodeDetails.text": @"episode_details", 
                   }]; 

    episodesEntityMapping.identificationAttributes = @[ @"episode_id" ]; 


    RKResponseDescriptor *episodesResponseDescriptor = 
    [RKResponseDescriptor responseDescriptorWithMapping:episodesEntityMapping 
               method:RKRequestMethodAny 
              pathPattern:self.resourcePath 
               keyPath:self.keyPath 
              statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 


    [model.objectManager addResponseDescriptor:episodesResponseDescriptor]; 

} 

MediaListViewController

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // setup delegates 
    NSAssert(dataSource, @"Datasource of MediaListViewController cannot be nil"); 
    dataSource.tableViewController = self; 
    self.tableView.dataSource = dataSource; 

    // setup refresh controller 
    UIRefreshControl *refreshControl = [UIRefreshControl new]; 
    [refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged]; 
    self.refreshControl = refreshControl; 

    // load data 
    [dataSource addResponseDescriptor]; 
    [dataSource downloadData]; 
    Controller *controller = [Controller getSingleton]; 
    UIView *background = [[UIView alloc] initWithFrame:controller.window.frame]; 
    [background setBackgroundColor:[UIColor redColor]]; 
    [background setTag:999]; 
    [[self.tableView superview] addSubview:background]; 
    [[self.tableView superview] sendSubviewToBack:background]; 
} 

EpisodesDataSource的DataSource繼承:其中有:

- (NSFetchedResultsController *)fetchedResultsController 
{ 
    // reset 
    [NSFetchedResultsController deleteCacheWithName:@"Master"]; 

    if (_fetchedResultsController != nil) { 
     return _fetchedResultsController; 
    } 

    NSManagedObjectContext *context =((Model *)[Model getSingleton]).managedObjectStore.mainQueueManagedObjectContext; 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.entityName 
               inManagedObjectContext:context]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:self.sortKey ascending:NO]; 
    NSArray *sortDescriptors = @[sortDescriptor]; 

    [fetchRequest setSortDescriptors:sortDescriptors]; 

    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController 
    = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
              managedObjectContext:context 
              sectionNameKeyPath:nil 
                cacheName:@"Master"]; 
    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    NSError *error = nil; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     // Replace this implementation with code to handle the error appropriately. 
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return _fetchedResultsController; 
} 

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{ 
    [tableViewController.tableView beginUpdates]; 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    [tableViewController.tableView endUpdates]; 
} 
+1

你在做什麼並不明顯,但爲什麼你沒有對fetchedResultsController的謂詞?我希望有某種謂詞可以選擇僅與節目相關的片段。所以像'@「程序==%@」,程序'。它看起來像每次向Core Data添加劇集,然後使用fetchedResultsController在Episodes tableView中顯示它們。所以每次你拉回之前加載的所有情節。 –

+0

@DuncanGroenewald嘿呀我只是做嘗試謂詞的解決方案(我不得不這樣,它實際上包括每集節目ID更新服務)..它的工作..但現在的問題是,我必須點擊同一程序細胞兩次爲它加載程序(即我第一次點擊它..沒有顯示..我回去..我再次點擊它,它的工作!我不知道爲什麼) – abbood

+0

做一些調試。拉動刷新顯示項目?選中時,是否在謂詞中傳遞並使用了正確的數據? – Wain

回答

1

按照從@Duncan Groenewald註釋,你應該使用謂詞過濾掉數據存儲的內容,所以你只顯示一個子集。目前,您每次處理新的下載時都會顯示所有內容,您將獲得附加的表格視圖內容。


對於後續問題,檢查謂詞。當您希望匹配時(即將字符串「100」與數字100進行比較),被管理對象和謂詞中使用的類/數據類型不匹配可能導致失敗。

通常,託管對象中的所有相同類型的信息都應該匹配數據類型,並且當從主接口移動到詳細接口時,您應該傳遞託管對象(或託管對象的值)以確保您維護讀取/過濾時的一致性。

+0

按照謂語評論..我想我是幸運的B/CI也有在後臺控制..所以我所做的情節實體包含的程序ID它屬於..但我想知道如果我沒有那種控制的,我會如何解決這個問題.. – abbood

+0

你的意思是沒有控制匹配數據類型?或者不能控制來自服務器的數據? – Wain

+0

無法控制來自服務器的數據 – abbood