我有一个包含许多属性的类。设置每个属性后,我需要更新我的应用程序的UI。制定者看起来像这样:
@synthesize trackHighlightColour = _trackHighlightColour;
- (void)setTrackHighlightColour:(UIColor *)trackHighlightColour
{
_trackHighlightColour = trackHighlightColour;
[self updateUI];
}
我想使用一个宏,而不是输入10次。这就是我到目前为止所做的:
#if !defined(PROPERTY_SETTER)
#define PROPERTY_SETTER(PROPERTY_NAME, UPPER_PROPERTY_NAME) @synthesize (PROPERTY_NAME) = _(PROPERTY_NAME);\
\
- (void)set(UPPER_PROPERTY_NAME):(UIColor *)(PROPERTY_NAME)\
{\
_(PROPERTY_NAME) = (PROPERTY_NAME);\
[self updateUI];\
}
#endif
不幸的是,这有一些问题。
编译器不允许我传递属性名称,而是必须将其作为字符串传递:
@implementation FooClass
PROPERTY_SETTER(@“trackHighlightColour”,“TrackHighlightColour”);
@end
感觉太过于接近这种技术了。有没有人有任何建议?
答案 0 :(得分:3)
听起来你想要键值观察(KVO)。
答案 1 :(得分:2)
这是我与MRC一起使用的
#define GENERATE_RETAIN_SETTER(ATTRIBUTE_NAME, UPDATER) \
if (_##ATTRIBUTE_NAME != ATTRIBUTE_NAME) { \
[_##ATTRIBUTE_NAME release]; \
_##ATTRIBUTE_NAME = [ATTRIBUTE_NAME retain]; \
\
[self UPDATER]; \
}
用法
- (void)setColor:(UIColor*)color {
GENERATE_PROPERTY_SETTER(color, updateUI)
}
结果:
- (void)setColor:(UIColor*)color {
if (_color != color) {
[_color release];
_color= [color retain];
[self updateUI];
}
}
可以根据您的特定需求进行更改,但是无法在预处理器中大写字符串。使用最新的编译器,您可能会丢失@synthesize
,但要完全按照您想要的方式执行,您可以创建一个包含四个参数的宏
#define GENERATE_RETAIN_SETTER(PROPERTY, TYPE, SETTER, UPDATER) \
@synthesize PROPERTY = _##PROPERTY; \
\
- (void)SETTER:(TYPE*)PROPERTY { \
if (_##PROPERTY != PROPERTY) { \
[_##PROPERTY release]; \
_##PROPERTY = [PROPERTY retain]; \
\
[self UPDATER]; \
} \
}
使用
GENERATE_RETAIN_SETTER(color, UIColor, setColor, updateUI)
你应该
@synthesize color = _color;
- (void)setColor:(UIColor*)color {
if (_color != color) {
[_color release];
_color= [color retain];
[self updateUI];
}
}