创建一个将另一个对象与相同接口包裹的对象-KVC/KVO问题

发布于 2024-09-16 14:06:07 字数 326 浏览 9 评论 0原文

我需要在一个类层次结构中创建一个对象,该对象包装来自不同类层次结构的对象。它们都有非常相似的接口,我希望自动让我的包装器将它无法识别的消息转发到其目标,而不是实现它自己的属性。我使用这样的方法来实现此目的:

- (id)forwardingTargetForSelector:(SEL)sel 
{
    if ([self.wrappedObject respondsToSelector:sel])
        return self.wrappedObject;

    return self;
}

但这不适用于键值编码。如何让我的包装器以使用其包装对象的属性的方式实现键值编码?

I need to create an object in one class hierarchy that wraps an object from a different one. They both have very similar interfaces, and I'd like to automatically have my wrapper forward messages it doesn't recognize to its target in lieu of implementing its own properties. I got this to work using something like this:

- (id)forwardingTargetForSelector:(SEL)sel 
{
    if ([self.wrappedObject respondsToSelector:sel])
        return self.wrappedObject;

    return self;
}

But this doesn't work for key-value coding. How can I go about having my wrapper implement key-value coding in a way that uses the properties of its wrapped object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

画中仙 2024-09-23 14:06:07

您必须覆盖 valueForKey:setValue:forKey:。一个例子:

- (id)valueForKey:(NSString *)key {
  if (/* wrapped object has key */)
    return [self.wrappedObject valueForKey: key];
  else
    return [super valueForKey: key];
}

棘手的部分是确定包装对象确实实现的键。最简单的方法是对它们进行硬编码,但这不太好。如果你想做的事情非常通用,你可以使用 Objective-C 的反射 API 来做一些事情。这里有两个想法:

  • 您的所有属性实际上都是声明的属性。您可以使用运行时函数 class_getProperty 来检查它的存在并可选择提取其他信息。检查可能如下所示:if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}

  • 您的属性也可以只有访问器。那么您应该从键构造选择器并使用 [self.wrappedObject respondsToSelector: ...] 就像您所做的那样前。 getter 的名字是键加上一个冒号。然而,这样做的问题是属性具有不同的 getter/setter 名称。第一个选项绝对是最好的。

You'll have to overwrite valueForKey: and setValue:forKey:. An example:

- (id)valueForKey:(NSString *)key {
  if (/* wrapped object has key */)
    return [self.wrappedObject valueForKey: key];
  else
    return [super valueForKey: key];
}

The tricky part will be to determine the keys the wrapped object does implement. The easy way is to hard-code them, but that's not too nice. If you want to do it very generic, you'll do something using the reflection APIs of Objective-C. Here are two ideas:

  • All your properties are actually declared properties. You can use the runtime function class_getProperty to check it's existence and optionally extract additional information. The check could then look like this: if (class_getProperty([self.wrappedObject class], [key UTF8String]) != nil) {...}.

  • Your properties could also have accessors only. Then you should construct the selectors from the key and use [self.wrappedObject respondsToSelector: ...] just as you did before. The getter's name is the key plus a colon. The problem with this, however, is properties that have different getter/setter name. The first option is definitely the best.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文