8

我目前正在嘗試使用NSFetchedResultsController從核心數據填充我的項目中的UITableView。我使用的是自定義搜索與比較器(雖然我也嘗試了選擇,並有一個相同的問題):NSFetchedResultsController自定義排序沒有被調用

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

    /* 
    Set up the fetched results controller. 
    */ 
    // Create the fetch request for the entity. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES comparator:^(id s1, id s2) { 
      NSLog(@"Comparator"); 
     //custom compare here with print statement 
    }]; 
    NSLog(@"Sort Descriptor Set"); 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstLetterOfObject" cacheName:@"Objects"]; 
    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 
    if (![fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return fetchedResultsController; 

當我進入這個標籤,我已登錄遍佈程序,發現NSFetchedResultsController做在讀取時甚至不會輸入比較器塊。而是用一些默認排序方法對其進行排序。

但是,如果我使用objectName刪除並添加一個對象,它就會進入比較器塊並正確排序表。

爲什麼NSFetchedResultsController不會使用比較器進行排序,直到託管對象模型更改爲止?

注意:我試過關閉緩存,和/或在viewDidLoad中執行一次提取操作,但似乎我提取多少次並不重要,但是何時。出於某種原因,它只在對象模型更改後使用我的排序。

回答

8

有幾件事情我能想到。首先,雖然這可能不是你的問題,但你不能排序瞬態屬性。但更有可能的是,當在由SQL存儲支持的模型中進行排序時,比較器會「編譯」爲SQL查詢,並非所有Objective-C函數都可用。在這種情況下,執行提取後您需要在內存中進行排序。

編輯:看到這個doc,特別是提取謂詞和排序描述符部分。

+1

他們不是瞬態屬性,但你的其他建議絕對看起來可能是問題。唯一的問題是我依靠fetchedResults控制器向表視圖提供段名稱等,所以每次在內存中排序都很困難(我認爲)。你會如何推薦去做?而我的另一個問題就是爲什麼比較器塊在對象模型更改後工作?謝謝! – 2011-01-25 16:32:40

0

很抱歉,但你錯過了最後取部分代碼段?:

NSError *error; 
BOOL success = [aFetchedResultsController performFetch:&error]; 

不要忘記釋放過多的要求:

[fetchRequest release]; 
+0

不,我只是沒有將它包含在代碼片段中。如果這樣做更清楚,我已經包含了整個方法。 – 2011-01-25 15:46:35

1

我看到同樣的問題,並且解決它的一種方法是修改對象,保存更改並將其恢復到原始值並再次保存。

// try to force an update for correct initial sorting bug 
NSInteger count = [self.fetchedResultsController.sections count]; 
if (count > 0) { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0]; 
    count = [sectionInfo numberOfObjects]; 
    if (count > 0) { 
     NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
     NSString *name = [obj valueForKey:@"name"]; 
     [obj setValue:@"X" forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
     [obj setValue:name forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
    } 
} 
相關問題