Display / Synthesis of iVar Properties in Object c

I have a class that essentially acts as a lightweight shell class around another class. He thinks another class is like iVar. I want to be able to identify some properties (actually, somewhat actually) of iVar, but for this I need to write each accessory of properties as follows:

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

Of course, I have to do this for each individual property, which is a pain (there are about 30 of them). I would like to synthesize this, but I could not figure out how to do this.

Is it possible to synthesize?

Also, I cannot subclass .... well, I could do this, but it really is not recommended. The iVar class is really quite heavy (it implements CoreText). I would rather write methods manually.

+4
source share
2 answers

So, here is the solution I found ... turned out to be pretty simple as soon as you knew what to do. First rewrite '- (id) forwardingTargetForSelector: (SEL) aSelector' and return iVar:

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

When the runtime searches for a method and cannot find it, it will call this method to see if there is another object to forward the message to. Note that this method usually 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 remove the compiler errors / warnings you get when you try to send a message that has not been announced. This is easy to do by declaring a category that you are not implementing.

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

Until you execute the implementation somewhere, aka @implementation Class (category) , the compiler will not complain (it is assumed that the implementation is somewhere.).

Now the only drawback that I see is that if you change any properties in the iVar Class interface, you need to make sure that you update all other classes that use the method described above, otherwise you will encounter when another class tries send what is now the wrong method (and the compiler will not warn you in advance). However, this can be obtained. You can declare protocols in categories. So instead, you create a separate protocol for the iVar class and move the methods / properties you want from the iVar class to the protocol.

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

Add this protocol to the iVar subclass so that it now detects these methods declared in the protocol.

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

Finally, just add the protocol to the category. Therefore, instead of the above category with explicit declarations, you will have:

 @interface Class (iVarClassMethods) <iVarClassProtocol> @end 

Now, if you need to change any properties / methods that you want, you will change them in the protocol. Then the compiler will warn you when you try to send the wrong method to the forwarding class.

+4
source

I think you can forward messages to ivar:

 - (void) forwardInvocation: (NSInvocation*) invocation { [invocation invokeWithTarget:ivar]; } - (NSMethodSignature*) methodSignatureForSelector: (SEL) selector { NSMethodSignature *our = [super methodSignatureForSelector:selector]; NSMethodSignature *ivars = [ivar methodSignatureForSelector:selector]; return our ? our : ivars; } 

Then you need to hide or fake the type of your object, for example, by choosing id , otherwise the compiler will complain that your class does not implement these methods. Of course, it would be better if you could come up with some better design that would do without such tricks.

+2
source

Source: https://habr.com/ru/post/1398058/


All Articles