6

NSFetchedResultsController ve NSSortDescriptor kullanarak özel sıralama sağlamak istiyorum. NSSortDescriptor mesajı ile ayırma özel olarakNSFetchedResultController ile özel sıralama (alt sınıf NSSortDescriptor)

- (id) initWithKey: artan: seçici: toObject: mesaj, bir compareObject iptal etmek üzere, bir NSSortDescriptor türetilmiş bir sınıf kullanmaya çalıştı (here bakınız) mümkün değildir.

Sorunum, compareObject: toObject: her zaman çağrılmıyor olmasıdır. Görünüşe göre sadece veri zaten hafızadayken denir. Veriler ilk kez mağazadan alındığında, compareObject: toObject yerine bir veritabanı tabanlı sıralama kullanan bir sıralama optimizasyonu vardır. (bakınız here).

Soruma soru: NSFetchedResultscontroller, verileri sıralamak için compareObject: toObject: mesajını kullanmaya nasıl zorlanır? (ve büyük veri kümesiyle çalışır)

Bir çözüm, bir sqlite deposu yerine bir ikili depo kullanmaktır ancak bunu yapmak istemiyorum.

başka çözüm:
-Başlangıç ​​performFetch SQL ile veri sıralamak için (compareObject adı değil)
, verilere bir modifikasyon -hukukun ve ters.
-kall performFetch (karşılaştırınObject çağrılır)
Bu benim durumumda çalışıyor, ancak bir kesmek ve her zaman çalışacağından emin değilim (özellikle büyük veri kümesiyle (toplu iş boyutundan daha büyük)).

GÜNCELLEME: CoreDataBooks örneği ile çoğaltabilirsiniz. , RootViewController.m yılında

- (void)viewWillAppear:(BOOL)animated { 
    Book* book = (Book *)[NSEntityDescription insertNewObjectForEntityForName:@"Book" 
       inManagedObjectContext:[self fetchedResultsController].managedObjectContext]; 
    [[self fetchedResultsController] performFetch:nil]; 
    [[self fetchedResultsController].managedObjectContext deleteObject:book]; 
    [self.tableView reloadData]; 
} 

ile sıralama açıklayıcısı kodunu değiştirmek: RootViewController.m olarak
, bu çirkin kesmek eklemek

MySortDescriptor *myDescriptor = [[MySortDescriptor alloc] init]; 
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:myDescriptor, nil]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 

ekle MySortDescriptor sınıfı:

@implementation MySortDescriptor 

-(id)init 
{ 
    if (self = [super initWithKey:@"title" ascending:YES selector:@selector(compare:)]) 
    { 

    } 
    return self; 
} 

- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2 
{ 
    //set a breakpoint here 
    return [[object1 valueForKey:@"author" ] localizedCaseInsensitiveCompare:[object2 valueForKey:@"author" ] ]; 
} 

//various overrides inspired by [this blog post][3] 
- (id)copy 
{ 
    return [self copyWithZone:nil ]; 
} 
- (id)mutableCopy 
{ 
    return [self copyWithZone:nil ]; 
} 
- (id)mutableCopyWithZone:(NSZone *)zone 
{ 
    return [self copyWithZone:zone ]; 
} 
- (id)copyWithZone:(NSZone*)zone 
{ 
    return [[MySortDescriptor alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]]; 
} 
- (id)reversedSortDescriptor 
{ 
    return [[[MySortDescriptor alloc] initWithKey:[self key] ascending:![self ascending] selector:[self selector]] autorelease]; 
} 
@end 
+0

Verilerinizi NSSortDescriptor veya bazı NSSortDescriptor'ların bazı birleşimlerinin yetersiz olduğunu nasıl sıralamaya çalışıyorsunuz? – ImHuntingWabbits

+0

Bir referans noktasından uzaklıklarına göre noktaları sıralamaya çalışıyorum. Referans noktasını, NSSortDescriptor türetilmiş bir nesnede bir ivar olarak kapsüllemeyi umuyordum. – FKDev

+0

Hmm, bu ilginç bir soruna benziyor. Kesinlikle nesneleri hafızada tutmak zorunda kalacağınız gibi geliyor. Hedef varlığınızda "referencePoint" özelliği ve mesafe olarak adlandırılan geçici bir özellik olabilir. Referans noktası ve hedef varlık arasındaki mesafeyi hesaplamak için mesafe uygulayın, mesafeyi sıralayın. Alt sınıf fikrinizi daha iyi sevmeme rağmen. – ImHuntingWabbits

cevap

6

Sorunuza ve yorumlarına referans olarak. Nesneleri sıralamak için belleğe çekmeniz gerekecek. Hafızada bulunduktan sonra bir noktadan mesafeyi belirlemek için bir kolaylık yöntemi kullanabilirsiniz.

Bellek içine çektiğiniz nesnelerin sayısını azaltmak için, maksimum ve minimum değerleri hesaplayabilir ve ardından bunları filtreleyerek, sıralamadan önce aramanızın yarıçapını azaltabilirsiniz.

Bellekte olmadığı sürece hesaplanan bir değeri sıralamak mümkün değildir.

+0

Yani bir özel sıralama algoritması sağlamak istiyorsanız, combo UITableViewController + NSFetchedResultsController kullanmanın yararlarından yararlanamıyorum demektir. – FKDev

+1

, herhangi bir formun geçici verilerini sıralamaya çalışıyorsanız, sadece bir 'NSFetchedResultsController' kullanamazsınız. Sorun olan, ancak veri olan algoritma değildir. İçeriği bir "NSFetchedResultsController" veya başka bir gözlemci ("ZSContextWatcher" gibi) ile izlemeye devam edebilirsiniz, ancak nesneler belleğe yüklendikten sonra çalışmanız gerekir. –

+0

SQLite deposu yerine bir ikili depo kullanırsam, istediğimi yapabilirim. Bu çok kötü, Apple, performans açısından trajiyi anlayan kullanıcı için özel sıralama yapmanın bir yolunu sunmuyor. – FKDev