我有实体Application
和Process
,一个应用程序可以有多个进程,但一个进程只能有一个应用程序。我得到一个特定的应用程序实体:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let appfetchRequest = NSFetchRequest(entityName: "Application")
//appfetchRequest.returnsObjectsAsFaults = false
do{
let results = try managedContext.executeFetchRequest(appfetchRequest)
applications.addObjectsFromArray(results as! [NSMutableArray])
}catch let error as NSError{
print("Jakis blad z applications entity: \(error)")
}
let predicate:NSPredicate = NSPredicate(format: "name == %@", appTitle)
let application:NSArray = applications.filteredArrayUsingPredicate(predicate)
并在此我有关系(名为applicationprocesses
)。
我尝试以多种方式获取这些实体的数组,但没有人工作。
实际上,我有:
let processes = application.valueForKey("applicationprocesses").allObjects.first
print(processes?.valueForKey("applicationprocesses"))
这给了我:
Optional({(
<NSManagedObject: 0x7f945871b7a0> (entity: Application; id: 0xd000000000080002 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Application/p2> ; data: {
appcolor = "#3F3F3F";
appicon = bed;
applabel = Proces;
applabelplural = Procesy;
applicationprocesses = (
"0xd000000000140004 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Process/p5>",
"0xd000000000100004 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Process/p4>",
"0xd000000000180004 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Process/p6>",
"0xd0000000001c0004 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Process/p7>",
"0xd0000000000c0004 <x-coredata://00C2FE4A-143B-436E-B39B-A0A32C300B68/Process/p3>"
);
companyid = 392;
id = 1261;
name = "aplikacja 1";
processescount = 5;
})
)})
我需要在UITablewView
中显示这些进程,所以我需要一个数组。
我将不胜感激任何帮助。
答案 0 :(得分:1)
您遇到的问题不是某处代码行不好的结果。它实际上正如它应该的那样工作。但是,您可以更轻松地使用NSManagedObject
从您的数据库中获取任何内容都会产生[AnyObject]
。如果你保持原样,你就不得不使用键值编码,这很痛苦,很容易搞砸。
但是,从CD实体创建类并向下转换获取结果非常简单。这是CoreData的一个很棒的功能,遗憾的是它不够紧张。
您的相关实体可能如下所示:
转到菜单 - &gt;编辑 - &gt;创建....
选择要为其创建子类的实体。
新文件将显示在您的项目中:
现在你可以使用这样的代码:
插入对象
注意.... as? Company
这是向下倾斜。
它允许您从CD实体访问属性,就像访问Struct或Class中的任何属性一样。
func createACompany() {
// no appDel here. appDel and managedContext are best declared in the class scope. See gist for entire ViewController
guard let moc = managedContext else { return }
guard let company = NSEntityDescription.insertNewObjectForEntityForName("Company", inManagedObjectContext: moc) as? Company else {
return // guard is handy to "abort"
}
company.name = "Apple"
guard let bob = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as? Employee else {
return
}
bob.name = "Bob"
bob.company = company
do {
try moc.save()
} catch {
print("core data save error : \(error)")
}
moc.refreshAllObjects()
}
获取对象
func fetchCompanies() -> [Company] {
guard let moc = managedContext else { return [] }
let request = NSFetchRequest(entityName: "Company")
request.returnsObjectsAsFaults = true
do {
let results = try moc.executeFetchRequest(request)
guard let companies = results as? [Company] else {
return []
}
return companies
}catch let error as NSError{
print("core data fetch error: \(error)")
return []
}
}
获取相关对象
仔细查看guard
声明。
let employeeSet = company.employees
- &gt;解开可选的NSSet
let employees = employeeSet.allObjects
- &gt;获取NSSet
as? [Employee]
- &gt;将allObjects
的结果向下转换为Array
Employee
func getEmployees(forCompany company : Company) -> [Employee] {
guard let employeeSet = company.employees, let employees = employeeSet.allObjects as? [Employee] else {
return []
}
return employees
}
旁注:
如果你改变了对班级命名的看法,你就会在任何地方改变它。别忘了在这里更新它:
必须更新类字段。
与InterfaceBuilder类似。如果您更改了班级名称,将无法再找到它。
答案 1 :(得分:0)
我相信您希望让所有托管对象(进程)与您已经拥有的应用程序对象相关。我们通常使用&#34;实体&#34;与数据库中的表格相同的词语。
对不起,我没有为这行代码提供快速版本。我不确定我的快速技能
NSArray * processes = [[application fristObject] objectIDsForRelationshipNamed:@&#34; applicationprocesses&#34;]
然后使用API将objectID转换为ManagedObject
- (__ kindof NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID;
唯一的问题是这个API,(NSArray *)objectIDsForRelationshipNamed:(NSString *)密钥,仅从版本8.3支持