NSFetchedResultsController с разделами, созданными первой буквой строки

От командной строки используйте утилиту Windows "sc.exe". Вы выполните что-то вроде этого:

sc delete <service-name>
70
задан jszumski 3 May 2013 в 13:38
поделиться

2 ответа

Подход Дейва Делонга хорош, по крайней мере, в моем случае, если вы опускаете пару вещей. Вот как это работает для меня:

  • Добавьте новый необязательный строковый атрибут субъекту, названному "lastNameInitial" (или что-то для этот эффект).

    Сделайте это свойство временным. Эта означает, что Core Data не побеспокоит сохраняя его в свой файл данных. Эта свойство будет существовать только в памяти, когда вам это нужно.

    Создайте файлы классов для этого entity.

    Не беспокойтесь о сеттере для этого свойство. Создайте этот геттер (это половина магии, ИМХО)


// THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL
- (NSString *) committeeNameInitial {
    [self willAccessValueForKey:@"committeeNameInitial"];
    NSString * initial = [[self committeeName] substringToIndex:1];
    [self didAccessValueForKey:@"committeeNameInitial"];
    return initial;
}


// THIS GOES IN YOUR fetchedResultsController: METHOD
// Edit the sort key as appropriate.
NSSortDescriptor *nameInitialSortOrder = [[NSSortDescriptor alloc] 
        initWithKey:@"committeeName" ascending:YES];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];

NSFetchedResultsController *aFetchedResultsController = 
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
        managedObjectContext:managedObjectContext 
        sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];

ПРЕДЫДУЩИЙ: Следуя начальным шагам Дэйва к письму, возникли проблемы, когда он умирает при setPropertiesToFetch с недопустимым исключением аргумента. Я зарегистрировал код и информацию об отладке ниже:

NSDictionary * entityProperties = [entity propertiesByName];
NSPropertyDescription * nameInitialProperty = [entityProperties objectForKey:@"committeeNameInitial"];
NSArray * tempPropertyArray = [NSArray arrayWithObject:nameInitialProperty];

//  NSARRAY * tempPropertyArray RETURNS:
//    <CFArray 0xf54090 [0x30307a00]>{type = immutable, count = 1, values = (
//    0 : (<NSAttributeDescription: 0xf2df80>), 
//    name committeeNameInitial, isOptional 1, isTransient 1,
//    entity CommitteeObj, renamingIdentifier committeeNameInitial, 
//    validation predicates (), warnings (), versionHashModifier (null), 
//    attributeType 700 , attributeValueClassName NSString, defaultValue (null)
//    )}

//  NSInvalidArgumentException AT THIS LINE vvvv
[fetchRequest setPropertiesToFetch:tempPropertyArray];

//  *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
//    reason: 'Invalid property (<NSAttributeDescription: 0xf2dfb0>), 
//    name committeeNameInitial, isOptional 1, isTransient 1, entity CommitteeObj, 
//    renamingIdentifier committeeNameInitial, 
//    validation predicates (), warnings (), 
//    versionHashModifier (null), 
//    attributeType 700 , attributeValueClassName NSString, 
//    defaultValue (null) passed to setPropertiesToFetch: (property is transient)'

[fetchRequest setReturnsDistinctResults:YES];

NSSortDescriptor * nameInitialSortOrder = [[[NSSortDescriptor alloc]
    initWithKey:@"committeeNameInitial" ascending:YES] autorelease];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
    initWithFetchRequest:fetchRequest 
    managedObjectContext:managedObjectContext 
    sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];
62
ответ дан 24 November 2019 в 13:22
поделиться

Here's how you might get it to work:

  • Add a new optional string attribute to the entity called "lastNameInitial" (or something to that effect).
  • Make this property transient. This means that Core Data won't bother saving it into your data file. This property will only exist in memory, when you need it.
  • Generate the class files for this entity.
  • Don't worry about a setter for this property. Create this getter (this is half the magic, IMHO)

    - (NSString *) lastNameInitial {
    [self willAccessValueForKey:@"lastNameInitial"];
    NSString * initial = [[self lastName] substringToIndex:1];
    [self didAccessValueForKey:@"lastNameInitial"];
    return initial;
    }
  • In your fetch request, request ONLY this PropertyDescription, like so (this is another quarter of the magic):

    NSDictionary * entityProperties = [myEntityDescription propertiesByName];
    NSPropertyDescription * lastNameInitialProperty = [entityProperties objectForKey:@"lastNameInitial"];
    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:lastNameInitialProperty]];
  • Make sure your fetch request ONLY returns distinct results (this is the last quarter of the magic):

    [fetchRequest setReturnsDistinctResults:YES];
  • Order your results by this letter:

    NSSortDescriptor * lastNameInitialSortOrder = [[[NSSortDescriptor alloc] initWithKey:@"lastNameInitial" ascending:YES] autorelease];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastNameInitialSortOrder]];
  • execute the request, and see what it gives you.

If I understand how this works, then I'm guessing it will return an array of NSManagedObjects, each of which only has the lastNameInitial property loaded into memory, and who are a set of distinct last name initials.

Good luck, and report back on how this works. I just made this up off the top of my head and want to know if this works. =)

15
ответ дан 24 November 2019 в 13:22
поделиться