【问题标题】:An Xcode macro for creating property setters用于创建属性设置器的 Xcode 宏
【发布时间】:2013-03-21 08:02:22
【问题描述】:

我有一个包含许多属性的类。设置每个属性后,我需要更新应用程序的 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

不幸的是,这有一些问题。

  1. (次要)需要用两个大小写重复属性名称
  2. 编译器不允许我传递属性名称,而是必须将其作为字符串传递:

    @implementation FooClass

    PROPERTY_SETTER(@"trackHighlightColour", "TrackHighlightColour");

    @结束

放弃这种技术感觉太接近了。有人有什么建议吗?

【问题讨论】:

  • 这看起来是一个使用 Key Value Observation 而不是宏和在每个 setter 中直接更新 UI 的好地方。你考虑过吗?大写/小写问题将是宏中难以解决的问题。
  • @gaige 从这个问题stackoverflow.com/questions/5893392/…看来,用于观察“自我”的 KVO 似乎不是一个优雅的解决方案。
  • 这当然不是我的经验。当然,无论如何模型都不应该更新 GUI(控制器应该观察模型类并更新 GUI),但是观察 self 很容易工作并将 KVO 信息传递给 super 是微不足道的。唯一的问题是从你不知道他们是否已经在做 KVO 的类继承,这应该不是问题。

标签: ios objective-c xcode macros


【解决方案1】:

听起来你想要键值观察 (KVO)。

【讨论】:

【解决方案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];
    }
}

【讨论】:

  • 仍然比我想要的多几行代码。但这仍然是一个相当不错的解决方案 - 谢谢!
  • @ColinE 只是稍微扩展了答案。
  • 你试过你的更新版本了吗?将GENERATE_PROPERTY_SETTER(color, UIColor, setColor, updateUI) 弹出到类的主体中会导致编译错误。
  • @ColinE 刚刚检查过,它对我有用,但我的宏名称有误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 2010-12-01
  • 2012-06-06
  • 2015-12-28
  • 1970-01-01
  • 2019-10-13
相关资源
最近更新 更多