NSTokenFieldCell 子类强制使用核心数据对多关系
我遇到了一个有趣的难题(当然,我可能只是做了一些非常错误的事情)。
我希望 NSTokenField 来“表示”核心数据应用程序中的关系。前提是这样的:您单击 TableView 中的注释(从注释数组控制器加载)。然后,标记字段(通过“值”)绑定到 Notes 数组控制器选择.Tags。标签是实体注释上的一对多关系。
显然,NSTokenField 不会接受数组控制器提供的 NSSet。为了解决这个问题,我对 NSTokenFieldCell 进行了子类化并重写了其 objectValue
和 setObjectValue:
方法。我认为我可以简单地将提供的 NSSet 转换为 NSTokenFieldCell 期望的 NSArray。 (注意:我最初尝试在 NSTokenField 子类上重写这些方法;但是,它们没有被调用。)
因此,我想出了上述代码:
- (void)setObjectValue:(NSSet*)object {
tagsList = [object copy];
NSMutableArray *displayList = [[NSMutableArray alloc] init];
for (id newObject in tagsList) {
[displayList addObject:[newObject valueForKey:@"Name"]];
}
[super setObjectValue:displayList];
}
- (id)objectValue {
NSArray *displayList = [super objectValue];
NSEntityDescription *tagEntity = [NSEntityDescription
entityForName:@"Tag"
inManagedObjectContext:[appDelegate
managedObjectContext]];
NSMutableSet *returnValue = [[NSMutableSet alloc] init];
for (NSString *token in displayList) {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:tagEntity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"Name == %@", token];
[request setPredicate:predicate];
NSError *error;
NSArray *results = [[appDelegate managedObjectContext] executeFetchRequest:request error:&error];
if (results == nil) {
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:[appDelegate managedObjectContext]];
[object setValue:token forKey:@"Name"];
[returnValue addObject:object];
} else {
[returnValue addObject:[results objectAtIndex:0]];
}
}
return returnValue;
}
它崩溃了。 :( 而且,令人惊讶的是,它在调用 [super objectValue]
的线路上崩溃了。它给了我错误:
-[NSConcreteAttributedString countByEnumerateWithState:objects:count:]: unrecognized selector sent to instance 。 ..
遗憾的是,当我进入 Core Data XML 文件并给 Note 一个标签时,它会正确显示,并且 [super setObjectValue:]
会传递一个数组但是,当我输入其他内容并将鼠标移开时,
我不知道该怎么办,谢谢
。 如果有什么不同,我没有为 TokenField 配置委托。
I have come across an interesting conundrum (of course, I could just being doing something horribly wrong).
I would like an NSTokenField to "represent" a relationship in a Core Data Application. The premise is such: You click on a Note from a TableView (loaded from the Notes Array Controller). The token field is then bound (through "value") to the Notes Array Controller selection.Tags. Tags is a to-many relationship on the entity Notes.
Obviously, an NSTokenField will not accept the NSSet that the Array Controller Provides it. To get around this, I subclassed NSTokenFieldCell and overrode its objectValue
and setObjectValue:
methods. I thought that I could simply translate the NSSet that was being provided to the NSArray that the NSTokenFieldCell expected. (Note: I originally tried overriding these methods on a NSTokenField subclass; however, they were not being called.)
So, I came up with said code:
- (void)setObjectValue:(NSSet*)object {
tagsList = [object copy];
NSMutableArray *displayList = [[NSMutableArray alloc] init];
for (id newObject in tagsList) {
[displayList addObject:[newObject valueForKey:@"Name"]];
}
[super setObjectValue:displayList];
}
- (id)objectValue {
NSArray *displayList = [super objectValue];
NSEntityDescription *tagEntity = [NSEntityDescription
entityForName:@"Tag"
inManagedObjectContext:[appDelegate
managedObjectContext]];
NSMutableSet *returnValue = [[NSMutableSet alloc] init];
for (NSString *token in displayList) {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:tagEntity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"Name == %@", token];
[request setPredicate:predicate];
NSError *error;
NSArray *results = [[appDelegate managedObjectContext] executeFetchRequest:request error:&error];
if (results == nil) {
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:[appDelegate managedObjectContext]];
[object setValue:token forKey:@"Name"];
[returnValue addObject:object];
} else {
[returnValue addObject:[results objectAtIndex:0]];
}
}
return returnValue;
}
It crashes. :( And, surprisingly it crashes on the line that calls [super objectValue]
. It gives me the error:
-[NSConcreteAttributedString countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance ...
Sigh. The sad thing is that when I go into the Core Data XML file and give the Note a Tag, it displays correctly, and [super setObjectValue:]
is passed an array of strings. However, as soon as I enter something else and mouse away, I get the error.
I am not sure what to do about this. Can anyone spot anything horribly wrong with this? Thanks.
UPDATE:
If it makes a difference, I do not have a delegate configured for the TokenField.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以典型的 SO 方式,我找到了自己问题的答案。一开始就很愚蠢。我只需要另一个绑定到 Notes Selection.Tags 集的 ArrayController。然后,我将 NSTokenField 绑定到该控制器的 ArrangedObjects,实现了一些委托方法。繁荣。简单的。
愚蠢的我。
In typical SO fashion, I found the answer to my own question. It was silly to begin with. I simply needed another ArrayController bound to the Notes selection.Tags set. Then, I bound the NSTokenField to the ArrangedObjects of that Controller, implemented some delegate methods. Boom. Simple.
Silly me.