Gre*_*mbs 70 iphone core-data objective-c ios
在iPhone上学习核心数据.核心数据似乎很少有用于填充表格视图的示例.该CoreDataBooks示例使用节,但他们是从模型中的满弦产生.我想通过姓氏的第一个字母,即地址簿,将核心数据表组织成各个部分.
我可以进入并为每个人创建另一个属性,即单个字母,以便充当分区,但这看起来很笨拙.
这就是我开始的......诀窍似乎在愚弄sectionNameKeyPath:
- (NSFetchedResultsController *)fetchedResultsController {
//.........SOME STUFF DELETED
// Edit the sort key as appropriate.
NSSortDescriptor *orderDescriptor = [[NSSortDescriptor alloc] initWithKey:@"personName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:orderDescriptor, nil];
[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:managedObjectContext
sectionNameKeyPath:@"personName" cacheName:@"Root"];
//....
}
Run Code Online (Sandbox Code Playgroud)
Gre*_*mbs 62
Dave DeLong的方法很好,至少在我的情况下,只要你省略了几件事.以下是它如何为我工作:
将新的可选字符串属性添加到名为"lastNameInitial"的实体(或其他类似的效果).
使此属性瞬态.这意味着Core Data不会将其保存到您的数据文件中.当您需要时,此属性将仅存在于内存中.
生成此实体的类文件.
不要担心这个属性的setter.创造这个吸气剂(这是神奇的一半,恕我直言)
// 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"];
Run Code Online (Sandbox Code Playgroud)
以前:遵循Dave的初始步骤生成的问题,它在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"];
Run Code Online (Sandbox Code Playgroud)
Gre*_*mbs 54
我想我还有另一种选择,这个选项在NSString上使用了一个类别......
@implementation NSString (FetchedGroupByString)
- (NSString *)stringGroupByFirstInitial {
if (!self.length || self.length == 1)
return self;
return [self substringToIndex:1];
}
@end
Run Code Online (Sandbox Code Playgroud)
现在稍后,在构建你的FRC时:
- (NSFetchedResultsController *)newFRC {
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:awesomeRequest
managedObjectContext:coolManagedObjectContext
sectionNameKeyPath:@"lastName.stringGroupByFirstInitial"
cacheName:@"CoolCat"];
return frc;
}
Run Code Online (Sandbox Code Playgroud)
这是我最喜欢的方法.更清洁/更容易实施.此外,您不必对对象模型类进行任何更改即可支持它.这意味着它将适用于任何对象模型,前提是节名称指向基于NSString的属性
Dav*_*ong 15
以下是您可以如何使用它:
不要担心这个属性的setter.创造这个吸气剂(这是神奇的一半,恕我直言)
- (NSString *) lastNameInitial {
[self willAccessValueForKey:@"lastNameInitial"];
NSString * initial = [[self lastName] substringToIndex:1];
[self didAccessValueForKey:@"lastNameInitial"];
return initial;
}在您的获取请求中,仅请求此PropertyDescription,就像这样(这是魔法的另一个四分之一):
NSDictionary * entityProperties = [myEntityDescription propertiesByName];
NSPropertyDescription * lastNameInitialProperty = [entityProperties objectForKey:@"lastNameInitial"];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:lastNameInitialProperty]];
确保您的获取请求仅返回不同的结果(这是魔法的最后四分之一):
[fetchRequest setReturnsDistinctResults:YES];
通过这封信订购你的结果:
NSSortDescriptor * lastNameInitialSortOrder = [[[NSSortDescriptor alloc] initWithKey:@"lastNameInitial" ascending:YES] autorelease];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastNameInitialSortOrder]];
执行请求,看看它给你的是什么.
如果我理解它是如何工作的,那么我猜它会返回一个NSManagedObjects数组,每个NSManagedObjects只有lastNameInitial属性加载到内存中,并且是一组不同的姓氏首字母.
祝你好运,并报告这是如何运作的.我只是把它从头顶上做起来想知道这是否有效.=)
小智 8
我喜欢Greg Combs上面的回答.我做了一些修改,以便通过将字符串转换为大写字母来使"Smith"和"smith"等字符串出现在同一节中:
- (NSString *)stringGroupByFirstInitial {
NSString *temp = [self uppercaseString];
if (!temp.length || temp.length == 1)
return self;
return [temp substringToIndex:1];
}
Run Code Online (Sandbox Code Playgroud)
小智 6
我一直遇到这个问题.我总是回到最好的解决方案是给实体一个真正的第一个初始属性.作为一个真实的字段提供更有效的搜索和排序,因为您可以将字段设置为索引.在首次导入/创建数据时,将第一个初始值拉出并用它填充第二个字段似乎并不是太多工作.您必须以任何方式编写初始解析代码,但是您可以为每个实体执行一次,而不是再次执行.缺点似乎是你每个实体(和索引)真正存储一个额外的字符,这可能是微不足道的.
一个额外的说明.我回避修改生成的实体代码.也许我错过了一些东西,但是用于生成CoreData实体的工具并不尊重我可能放在那里的任何代码.我生成代码时选择的任一选项都会删除我可能进行的任何自定义.如果我用聪明的小函数填充我的实体,那么我需要向该实体添加一堆属性,我无法轻松地重新生成它.
| 归档时间: |
|
| 查看次数: |
38957 次 |
| 最近记录: |