本文介绍了在目标c中公开/合成iVar属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,该类实际上是另一个类的轻量级包装类.它把其他类称为iVar.我希望能够公开iVar的某些属性(实际上很多),但是要做到这一点,我必须像这样写出每个属性访问器:

I have a class that essentially acts as a light weight wrapper class around another class. It holds that other class as an iVar. I want to be able to expose certain properties (quite a few actually) of the iVar, but to do so I have to write out each property accessor like so:

- (void) setProperty:(Class *)value{
    _iVar.property = value;
}
- (Class *) property{
    return  _iVar.property;
}

当然,我必须为每个属性执行此操作,这很痛苦(大约有30个属性).我很希望能够对此进行综合,但是我还无法弄清楚该如何做.

Of course, I have to do this for every single property, which is a pain (there are about 30 of them). I would love to be able to synthesize this but I haven't been able to figure out how.

可以合成吗?

而且,我不能继承....好吧,我也许可以,但是实际上不建议这样做. iVar类确实很繁重(它实现了CoreText).我宁愿手工写出这些方法.

Also, I can't subclass....well, I might be able to but it's really not recommended. The iVar class is really quite heavy (it implements CoreText). I'd rather write out the methods by hand.

推荐答案

好,所以这是我发现的解决方案.一旦知道要做什么,就变得非常简单.首先覆盖'-(id)forwardingTargetForSelector:(SEL)aSelector'并返回iVar:

Ok, so here's the solution I found...ended up being pretty simple once you knew what to do. First overwrite '- (id) forwardingTargetForSelector:(SEL)aSelector' and return the iVar:

- (id) forwardingTargetForSelector:(SEL)aSelector{
    return iVar;
}

当运行时正在寻找一个方法而找不到一个方法时,它将调用此方法以查看是否存在另一个对象将消息转发到该方法.请注意,此方法通常返回nil,如果在此处返回nil,则程序将崩溃(这是适当的行为).

When the runtime is looking for a method and cannot find one, it will call this method to see if there is another object to forward the message to. Note that this method normally returns nil and if you return nil here, your program will crash (which is the appropriate behavior).

问题的第二部分是消除当您尝试发送未声明的消息时收到的编译器错误/警告.通过声明您未实现的类别,可以轻松完成此操作.

The second part of the problem is to shush the compiler errors/warnings you'll get when you try to send a message that's not declared. This is easily done by declaring a category you don't implement.

@interface Class (iVarClassMethods)
@propoperty (strong) Class *property1;
......more properties
@end

只要您不在任何地方(也称为@implementation Class (category))放置实现,编译器就不会抱怨(它将假定实现在某处.... ).

As long as you don't put in an implementation anywhere, aka @implementation Class (category), the compiler won't complain (it'll assume that the implementation is somewhere....).

现在我看到的唯一缺点是,如果您更改了iVar类的接口中的任何属性,则需要确保更新使用上述方法的所有其他类,否则,当另一个类出现时,您将崩溃尝试发送错误的方法(并且编译器不会事先警告您).但是,此 可以解决.您可以在类别中声明协议.因此,您可以为iVar类创建一个单独的协议,然后将所需的方法/属性从iVar类中移出到协议中.

Now the only drawback I see is if you change any of the properties in the interface of the iVar Class, you need to make sure you update all other classes that use the method described above, otherwise you'll crash when another class tries to send what is now the wrong method (and the compiler won't warn you beforehand). However, this can be gotten around. You can declare protocols in a category. So instead you create a separate protocol for the iVar class and move the methods/properties you wish out of the iVar class into the protocol.

@protocol iVarClassProtocol
@propoperty (strong) Class *property1;
......more properties
@end

将该协议添加到iVar子类中,以便它具有通过该协议声明的那些方法.

Add that protocol to the iVar subclass so it has those methods declared through the protocol now.

@interface iVarClass <iVarClassProtocol>
....other methods/properties you don't need forwarded
@end

最后,只需将协议添加到类别中.因此,除了前面提到的带有显式声明的类别,您将拥有:

Finally, simply add the protocol to the category. So instead of the aforementioned category with explicit declarations you'll have:

@interface Class (iVarClassMethods) <iVarClassProtocol>
@end

现在,如果您需要更改任何待修改的属性/方法,请在协议中进行更改.当您尝试将错误的方法发送到转发类时,编译器会警告您.

Now, if you need to change any of the to-be-fowarded properties/methods, you change them in the protocol. The compiler will then warn you when you try to send the wrong method to the forwarding class.

这篇关于在目标c中公开/合成iVar属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 22:13