Is there any way to force/cajole/encourage Interface Builder into running the C preprocessor when scanning source files for IBOutlet references?
It's a tricky problem, I can see, since in an ideal world it would need to preprocess the file with the same context that the project would, ie with the precompiled headers etc (this is much more likely to work when IB is integrated into XCode I would guess).
I have some property-related macro trickery that I want to do.
Leaving aside the reason for the macros in the first place (since it's not particularly relevant to this question, other than providing a motivation), my big stumbling block is that IB is pretty simplistic in the way that it recognises outlets. If I use my macros,开发者_C百科 I can't persuade IB to spot outlets.
For example if I wanted to replace:
@property (retain, nonatomic) IBOutlet UIWindow* window;
with my macros, it would look something like this:
ECPropertyDefine(window, UIWindow*, retain, nonatomic);
Unfortunately, it's obvious that by default IB doesn't perform any macro expansion, and thus has no clue that this is an outlet, regardless of whether I put IBOutlet into the macro definition, or into the parameters that I call the macro with.
I was just wondering whether there might be some obscure hook somewhere in IB which would allow a script to preprocess the source files as IB scans them.
As far as I know what you're trying to do won't work.
I don't think so. IB doesn't actually process, link or compile anything. It doesn't seem to activating any scripts at all.
You might could get around this by using a reverse insertion pattern. In the standard insertion pattern, you have a machine generated superclass and then a human written subclass. Automatic alterations of the machine class are transparently inherited by the human-written class (see MoGenerator for a good Objective-C example of this.) In the reverse insertion pattern, you would have a human-written superclass and then the machine generated (with macro expansion) subclasses. Then you would target IB at the machine class. The machine class would have the IBOutlet
marker so IB would pick it up.
You could add a script to the "Run Script" phase to run the C preprocessor and insert the machine files into the target.
My current workaround is to repeat a minimal property definition of any outlets, for the benefit of interface builder, like this:
#ifndef ECPropertyDefine
@property () IBOutlet UIWindow* window;
@property () IBOutlet UITabBarController* tabBarController;
#endif
This is ignored by gcc (because ECPropertyDefine is defined), but parsed by Interface Builder, which knows nothing about the #ifndef.
Not a great solution because I'm repeating the definition of the property, and they could end up inconsistent. I don't repeat the property attributes, which IB ignores.
精彩评论