gpt4 book ai didi

objective-c - NSTokenField 表示核心数据对多关系

转载 作者:太空狗 更新时间:2023-10-30 03:37:10 25 4
gpt4 key购买 nike

我在弄清楚如何在 NSTokenField 中表示多对多关系模型时遇到了问题。我有两个(相关)模型:

项目标签

一个项目可以有多个标签,一个标签可以有多个项目。所以这是一个反向的一对多关系。

我想做的是在 NSTokenField 中表示这些标签。我想以一个 tokenfield 自动建议匹配结束(找到一种使用 tokenfield:completionsForSubstring:indexOfToken:indexOfSelectedItem 来做到这一点的方法),并且如果它与现有标签实体不匹配,则能够添加新的标签实体。

好的,希望你还在我身边。我正在尝试使用绑定(bind)和数组 Controller 来完成所有这些工作(因为这最有意义,对吧?)

我有一个数组 Controller ,“Item Array Controller”,它绑定(bind)到我的应用委托(delegate) managedObjectContext。显示所有项目的 TableView 绑定(bind)到此数组 Controller 。

我的 NSTokenField 的值绑定(bind)到数组 Controller 选择键和模型键路径:标签。

使用此配置,NSTokenField 将不会显示标签。它只是给我:

<NSTokenFieldCell: 0x10014dc60>: Unknown object type assigned (Relationship objects for {(
<NSManagedObject: 0x10059bdc0> (entity: Tag; id: 0x10016d6e0 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Tag/p102> ; data: <fault>)
)} on 0x100169660). Ignoring...

这对我来说很有意义,所以不用担心。我查看了一些 NSTokenField 委托(delegate)方法,似乎我应该使用:

- (NSString *)tokenField:(NSTokenField *)tokenField displayStringForRepresentedObject:(id)representedObject

问题是,这个方法没有被调用,我得到了和以前一样的错误。

好的,所以我的下一步是尝试制作一个 ValueTransformer。从带有标签实体的数组转换为 -> 带有字符串(标签名称)的数组都很好。另一种方式更具挑战性。

我尝试的是在我的共享应用程序委托(delegate)托管对象上下文中查找每个名称并返回匹配的标签。这显然给我带来了不同托管对象上下文的问题:

Illegal attempt to establish a relationship 'tags' between objects in different contexts (source = <NSManagedObject: 0x100156900> (entity: Item; id: 0x1003b22b0 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Item/p106> ; data: {
author = "0x1003b1b30 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Author/p103>";
createdAt = nil;
filePath = nil;
tags = (
);
title = "Great presentation";
type = "0x1003b1150 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Type/p104>";
}) , destination = <NSManagedObject: 0x114d08100> (entity: Tag; id: 0x100146b40 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Tag/p102> ; data: <fault>))

我哪里错了?我该如何解决这个问题?它甚至是正确的方法吗(我觉得你必须使用 ValueTransformer 很奇怪?)

提前致谢!

最佳答案

我编写了一个自定义的 NSValueTransformer 来映射绑定(bind)的 NSManagedObject/Tag NSSetNSString token 字段的 NSArray。以下是 2 种方法:

- (id)transformedValue:(id)value {
if ([value isKindOfClass:[NSSet class]]) {
NSSet *set = (NSSet *)value;
NSMutableArray *ary = [NSMutableArray arrayWithCapacity:[set count]];
for (Tag *tag in [set allObjects]) {
[ary addObject:tag.name];
}
return ary;
}
return nil;
}

- (id)reverseTransformedValue:(id)value {
if ([value isKindOfClass:[NSArray class]]) {
NSArray *ary = (NSArray *)value;
// Check each NSString in the array representing a Tag name if a corresponding
// tag managed object already exists
NSMutableSet *tagSet = [NSMutableSet setWithCapacity:[ary count]];
for (NSString *tagName in ary) {
NSManagedObjectContext *context = [[NSApp delegate] managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"name = %@", tagName];
NSEntityDescription *entity = [NSEntityDescription entityForName:[Tag className] inManagedObjectContext:context];

[request setEntity:entity];
[request setPredicate:searchFilter];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if ([results count] > 0) {
[tagSet addObjectsFromArray:results];
}
else {
Tag *tag = [[Tag alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
tag.name = tagName;

[tagSet addObject:tag];
[tag release];
}
}
return tagSet;
}
return nil;
}

CoreData 似乎在返回时自动建立对象关系(但我还没有完全验证这一点)

希望对您有所帮助。

关于objective-c - NSTokenField 表示核心数据对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3880961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com