向 coreData 中的实体添加浮点属性,并在每次添加新对象时递增它
Posted
技术标签:
【中文标题】向 coreData 中的实体添加浮点属性,并在每次添加新对象时递增它【英文标题】:Adding a float attribute to an entity in coreData and increment it on every addition of new Object 【发布时间】:2012-11-06 06:55:20 【问题描述】:我是 coreData 的新手,我正在开发一个示例应用程序,在该示例应用程序中,我向名为“Test”的实体添加了一个名为 displayOrder 的浮点类型属性。我想在添加每个测试对象时增加这个显示顺序。为此,我编写了以下代码,但它不起作用,我想知道我哪里出错了
- (void)insertNewObject:(NSString *)fileName
Test *testName = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.managedObjectContext];
[testName setName:fileName];
NSManagedObject *lastObject = [self.controller.fetchedObjects lastObject];
float lastObjectDisplayOrder = [[lastObject valueForKey:@"displayOrder"] floatValue];
NSLog(@"%f",lastObjectDisplayOrder);
[testName setValue:[NSNumber numberWithDouble:lastObjectDisplayOrder + 1.0] forKey:@"displayOrder"];
// Save the context.
NSError *error = nil;
if (![self.managedObjectContext save:&error])
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
实际上,问题是它第一次递增,即从 0 到 1,但之后我总是得到 1。
问候 兰吉特
【问题讨论】:
NSLog(@"%f",lastObjectDisplayOrder);
怎么样?是否总是打印0
?
嗨@Aadhira,第一次是0 第二次是1,后来总是1
你能在你的获取结果控制器上显示排序描述符吗?似乎fetchedObjects lastObject
总是为`lastObjectDisplayOrder'返回值为1的对象
嗨@ChrisH,我想通了,现在假设,如果我想要objectAtIndex:0,而不是获取lastObject,我得到错误说明,arrayOutofbound index
如果您在数组的索引 0 处请求一个对象,并得到一个超出范围的错误,这意味着您的数组是空的。无论哪种方式,我都会说您的问题是您正在根据数组中错误对象的值增加lastObjectDisplayOrder
。如果数字与数组计数相同,为什么不将其用作您增加的值?
【参考方案1】:
您的问题可能与您加载 lastObject 的部分有关,并且您可能没有更新 fetchedresultscontroller,我建议创建一个 iVar 并在 init 或 viewDidLoad 上分配值,然后使用该 iVar 更新并获取正确的值,另外,如果您不为此使用小数,而您只需要顺序,那么 Integer 应该会更好。
【讨论】:
当我插入新对象时,我取消隐藏一个新的 ViewController,我在其中添加了对象的名称,然后我隐藏了 ViewController。所以我添加了iVar并在ViewDidLoad中获取了lastObject,然后它不可能因为它没有被调用,因为我只是隐藏了ViewController【参考方案2】:您可以使用核心数据聚合函数来获得最大的 displayOrder 值。
类似:
- (NSNumber *)nextDisplayOrder
NSManagedObjectContext *context = self.managedObjectContext;
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setResultType:NSDictionaryResultType];
NSExpression *keyExpression = [NSExpression expressionForKeyPath:@"displayOrder"];
NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyExpression]];
NSExpressionDescription *description = [[NSExpressionDescription alloc] init];
[description setName:@"maxDisplayOrder"];
[description setExpression:maxExpression];
[description setExpressionResultType:NSFloatAttributeType];
[request setPropertiesToFetch:[NSArray arrayWithObject:description]];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if (results.count == 1)
NSNumber *maxDisplayOrder = [[results objectAtIndex:0] valueForKey:@"displayOrder"];
return [NSNumber numberWithFloat:[maxDisplayOrder floatValue] + 1.f];
else
NSLog(@"Could not get next displayOrder. Error: %@", error);
return nil;
一些补充说明:
对于像 displayOrder 这样的离散值使用整数而不是浮点数 这个样板代码可以用MagicalRecord写成两行,所以你可能想看看 more info on aggregate functions【讨论】:
不确定。这里有很多未知数,而我发布的代码在任何情况下都应该可以工作,只要您在每次插入后保存 MOC 即可。您是否在每次插入调用之前重新加载 self.controller ?您是否按 displayOrder(获取请求的适当排序描述符)对对象进行排序? NSLog self.controller.fetchedObjects 并查看您的对象的外观。您还混合了 NSNumber double 和 float 方法,尽管这可能不是这里的问题。你真的应该为这个属性使用整数,我建议你改变模型。 是的,我正在按 displayOrder 对对象进行排序。如何使用您的函数,这是将值传递给属性的正确方法 [test setdisplayOrder:[self nextDisplayOrder]; 我正在尝试调用该函数并获取您的函数返回的值,但该函数在 NSArray *results = ... 行崩溃 对不起,我忘记将结果类型设置为 NSDictionaryResultType。现在应该没问题了。 我的代码也在工作,问题是我按降序排序。所以他们不需要使用魔法记录以上是关于向 coreData 中的实体添加浮点属性,并在每次添加新对象时递增它的主要内容,如果未能解决你的问题,请参考以下文章
如何在一个类中创建 CoreData 实体并在另一个类中访问?
Core Data 轻量级迁移 - 现有实体是不是添加了新属性?