CoreData 和 setPropertiesToFetch 只返回 1 个实体

Posted

技术标签:

【中文标题】CoreData 和 setPropertiesToFetch 只返回 1 个实体【英文标题】:CoreData and setPropertiesToFetch only returns 1 entity 【发布时间】:2013-02-13 22:33:03 【问题描述】:

我有一个使用 CoreData 来存储 Customer 实体的应用程序。每个Customer 实体都有一个customerNamecustomerID 和其他属性。

然后我显示所有Customers 的列表,仅显示他们的customerNamecustomerID

我可以通过执行获取请求来获取所有Customer 实体来完成此操作,但是我只需要显示customerNamecustomerID 属性。

问题 1: 我正在尝试使用 setPropertiesToFetch 仅指定这些属性,但每次它只返回数组中的 1 个对象。

这是我的方法的样子:

    NSFetchRequest *fetchRequest = [NSFetchRequest new];


    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSDictionary *entProperties = [entity propertiesByName];

    [fetchRequest setResultType:NSDictionaryResultType];
    [fetchRequest setReturnsDistinctResults:YES];

    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:[entProperties objectForKey:@"customerName"],[entProperties objectForKey:@"customerID"], nil]];

    [fetchRequest setFetchLimit:30];

    NSError *error;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    NSLog(@"fetched objects count = %d", [fetchedObjects count]);

    if (error) 
        NSLog(@"Error performing fetch = %@", [error localizedDescription]);
        return nil;
     else 
        NSLog(@"successful fetch of customers");
        for( NSDictionary* obj in fetchedObjects ) 
            NSLog(@"Customer: %@", [obj objectForKey:@"customerName"]);
        
        return fetchedObjects;
    

返回的一个对象没问题,所以我知道它至少抓取了一个Customer 对象customerNamecustomerID。我只需要它返回所有Customer 对象customerNamecustomerID

问题 2:

这是最好的方法吗?我的想法是数据库中可能有多达 10k+ 个 Customer 对象。因此,仅获取所需的属性以显示在表中而不是整个 Customer 对象将是内存效率的。

然后,当在表中选择客户时,我会获取整个 Customer 对象以显示其详细信息。

但是,我了解到,如果可以在不久的将来使用相应的实体,那么加载整个实体而不是仅加载其属性也是一种很好的做法。我想这个想法是单个获取请求比两个更好。

感谢您的帮助。

【问题讨论】:

如果取消获取限制会怎样? 【参考方案1】:

对于问题 1:这是我用 swift 编写的示例代码。我不断测试CoreData API,找到了这种调用方式。希望能帮到你。

let fetchRequest = NSFetchRequest<NSDictionary>(entityName: "Customer")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.propertiesToFetch = [
    #keyPath(Customer.customerID),
    #keyPath(Customer.customerName)
]

let customers: [NSDictionary]
do 
    customers = try managedObjectContext.fetch(fetchRequest)
    customers.forEach 
        print("CustomerID: \($0["customerID"]), CustomerName: \($0["customerName"])")
    
 catch 
    print(error.localizedDescription)

【讨论】:

【参考方案2】:

随机,

问题 2: 当您应该使用批量限制时,听起来您正在使用获取限制。批处理限制是一种基本的游标机制。它们旨在有效地处理内存。

W.r.t.问题 1,我坚信以自然方式编写应用程序,然后使用 Instruments 和其他工具来决定性能和内存优化。首先尝试让应用程序正确运行。那就快点吧。

安德鲁

【讨论】:

以上是关于CoreData 和 setPropertiesToFetch 只返回 1 个实体的主要内容,如果未能解决你的问题,请参考以下文章

Coredata 和 Mogenerator,coredata 标志并发问题 EXC_BAD_INSTRUCTION

CoreData、SourceList 和 NSTreeController

RestKit 和 Coredata

Coredata — 入门使用

NSFetchedResultsController、CoreData、SectionIndex 和特殊字符 (Umlaute..)

CoreData 和 RestKit