2017-08-02 3 views
0

En entité myCoredata (Personnes) Je veux aller chercher chercher toutes les personnes, triées par la longueur du nom alphabetically.I ont essayé le code suivantCoreData chercher avec NSSortDescriptor par ordre alphabétique et durée de la propriété

NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"first_name" ascending:YES]; 
NSSortDescriptor *lengthSorter = [NSSortDescriptor sortDescriptorWithKey:@“first_name.length" ascending:YES]; 
[fetchRequest setSortDescriptors:@[lengthSorter, nameSortDescriptor]]; 

Mais chance.Est-ce une approche complètement mauvaise? Comment suis-je censé faire quelque chose comme ça avec un fetch CoreData?

Répondre

0

Vous avez raison, cela ne fonctionnera pas. Les prédicats utilisés pour fetchRequest sont transformés en requêtes mySQL afin qu'ils n'acceptent pas tout ce qui est un prédicat valide (comme predicateWithBlock: par exemple).

Dans ce cas, je suggère d'ajouter une autre colonne dans la table (propriété de l'entité) pour firstNameLength. Ayez UNIQUEMENT une façon de définir le nom et de définir la propriété nameLength en même temps (afin qu'elle ne soit pas désynchronisée). Ensuite, vous pouvez simplement trier par la propriété nameLength qui a été pré-calculée.

De même, vous ne voudrez peut-être pas utiliser NSString.length, car cela ne veut peut-être pas dire ce que vous pensez. Les lettres qui ont des marques de décoration (comme "résumé") peuvent avoir une longueur plus longue que vous avez l'intention. Emoji peut également être 2 ou 4 ou 8 chaînes de longueur. Au lieu de cela, vous pouvez compter les séquences de caractères composées en utilisant enumerateSubstringsInRange:options:usingBlock:

0

Une façon de procéder consiste à ajouter une propriété avec un accesseur personnalisé à la sous-classe de votre entité de données principale. Si vous faites beaucoup de données de base, je suggère quelque chose comme mogenerator, ou les fonctions intégrées pour gérer la génération d'entités afin que vous n'écriviez pas vos classes de modèles chaque fois que vous changez le modèle.

@property (nonatomic, readonly, getter=getFirstNameLength) NSUInteger firstNameLength; 

-(NSUInteger)getFirstNameLength { 
    return [firstName length]; 
} 

Tant que cette méthode est publique dans la classe .h vous serez en mesure d'y accéder comme vous le feriez une propriété régulière de modèle dans votre prédicat.

+0

J'ai essayé ce code et je n'ai réussi à le faire fonctionner qu'avec un 'NSInMemoryStoreType'. Quand je l'ai essayé avec un 'SQLLiteStoreType', j'ai reçu une exception: 'NSInvalidArgumentException', raison: 'keypath firstNameLength non trouvé dans l'entité. Avez-vous eu ce travail d'une manière ou d'une autre? Pourriez-vous partager le code? –

+0

intéressant, je n'utilise pas le code exact mais je vais jeter un oeil. – SpaceTrucker

+0

J'utilisais une propriété personnalisée pour les index de défilement. dans une vue de table. J'ai remarqué que j'ai ajouté du code KVO avec self willAccessValueForKey et didAccessValueForKey autour de mon code de calcul. Je suis intrigué par la raison pour laquelle votre code ne fonctionnerait pas comme un magasin SQL. – SpaceTrucker