【问题标题】:Fetched Property in Core Data在核心数据中获取属性
【发布时间】:2012-10-12 13:39:50
【问题描述】:

在我的核心数据模型中,Person 具有一个或多个 Cars,由无序对多关系“汽车”指定。通常,我需要检索由datePurchaseddateLastUsed 订购的人员的汽车。

直到现在,我一直在为carsByDatePurchased 添加自己的方法到Person。这使用排序描述符对 NSSet cars 进行排序并返回一个 NSArray。

我可以/应该为此使用 Fetched 属性吗?每次我需要按特定顺序的汽车时,我都会使用排序描述符遇到一些性能开销,甚至可以实现我自己的 carsByDatePurchased 缓存。看起来为我缓存了获取的属性 - 对吗?

获取的属性与我自己的实现相比有哪些限制?

至关重要的是,获取的属性值在执行之间是否保持不变?如果我更新 fetched 属性并保存我的上下文,是否会在下次启动应用程序时存储该值?

【问题讨论】:

    标签: objective-c ios cocoa core-data nsmanagedobject


    【解决方案1】:
    AppDelegate *delegate = [UIApplication sharedApplication].delegate;
    NSManagedObjectContext *context = [delegate managedObjectContext];
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"DataRecord" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSError *error;
    fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *obj in fetchedObjects) {
        NSLog(@"Name: %@", [obj valueForKey:@"name"]);
        NSLog(@"Info: %@", [obj valueForKey:@"info"]);
        NSLog(@"Number: %@", [obj valueForKey:@"number"]);
        NSLog(@"Create Date: %@", [obj valueForKey:@"createDate"]);
        NSLog(@"Last Update: %@", [obj valueForKey:@"updateDate"]);
    }
    NSManagedObject *obj = [fetchedObjects objectAtIndex:0];
    [self displayManagedObject:obj];
    selectedObject = obj;
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
    • 如果它不是问题的答案,那么它一开始就不应该存在。在 Stack Overflow 上,答案必须提供问题的解决方案。
    【解决方案2】:

    获取的属性会起作用,实际上我在我自己的项目中使用了它,它具有需要按“添加日期索引”排序的 Post->Comment 关系。

    有一些注意事项:您不能在可视化编辑器中指定排序描述符,而必须在代码中指定。

    我用这样的东西

        // Find the fetched properties, and make them sorted...
    for (NSEntityDescription *entity in [_managedObjectModel entities])
    {
        for (NSPropertyDescription *property in [entity properties])
        {
            if ([property isKindOfClass:[NSFetchedPropertyDescription class]])
            {
                NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
                NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];
    
                // Only sort by name if the destination entity actually has a "index" field
                if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"index"])
                {
                    NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"index"
                                                                               ascending:YES];
    
                    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
                }
            }
        }
    }
    

    在我的帖子实体中,我有一个名为“sortedComments”的获取属性,其定义为:

    post == $FETCH_SOURCE
    

    post 有一对多的“cmets”关系,而 cmets 有一个“post”逆向

    与此处的其他答案相反:使用这样的获取属性的好处是,CoreData 负责缓存并将缓存作为帖子的 cmets 或实际上拥有它们的帖子更改。

    【讨论】:

      【解决方案3】:

      如果您想获得一些性能,请使用 NSFetchedResultsController 进行获取,并使其与缓存一起使用。下次您执行相同的提取时,提取会更快。在您的特定名称中,您将不得不缓存名称。看看 NSFetchedResultsController documentation

      【讨论】:

      • 但是缓存的结果会在两次启动之间持续存在吗?这是我正在寻找的一个关键部分。
      • 是的(因为回复不够长而填充)
      • 好吧好吧好吧。这可能是灵丹妙药。我今天会尝试这个。为了清楚起见,您建议使用 NSFetchedResultsController inside my cardsByDatePurchased 方法?此方法当前订购 self.cars 并返回数组 - 您是说应该使用结果控制器而不是获取汽车并对其进行排序而不是使用 cars.self?
      • 我立即注意到文档希望 FRC 用于更新表格视图,并提供为此格式化的结果。但是仅仅因为它的缓存机制而使用它是可以的(跟踪更改的委托也会很有用)?
      • @BenPackard:FRC 主要用作表格视图数据源,但不限于此。但是您必须至少实现一种委托方法才能启用更改跟踪。
      【解决方案4】:

      获取的属性基本上是一个获取请求。我不知道如何在 GUI 中向这些属性添加排序描述符,但我可能错了。但是为什么不在你的carsByDatePurchased 方法中创建一个获取请求并提供一个排序描述符呢?它返回一个数组或结果(您可以将其廉价地包装在 NSOrderedSet 中,并将 copyItems: 标志设置为 no)。

      【讨论】:

      • 这与简单地访问 self.cars 并应用排序描述符有什么区别?为什么我会受益于在 cardsByDatePurchased 中使用另一个获取请求而不是仅使用 self.cars?
      • 因为排序是在数据库级别执行的,而不是在从数据库中获取之后的内存。
      • 我应该获取所有汽车并使用谓词将它们限制为 person == self 吗?或者我可以以任何方式重复使用 self.cars 吗?
      • Self cars 为您提供与此人相关联的所有汽车,相当于执行与人平等的提取。所以你应该测试人的平等(personcars的反比关系)并添加排序描述符来对数据库引擎中的数据进行排序。
      • 很抱歉让您为我拼写出来,但“测试人员平等”意味着在获取时使用 NSPredicate,对吗?或者我应该在获取后过滤结果(记住性能是我的主要目标)
      猜你喜欢
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 2018-01-27
      相关资源
      最近更新 更多