0

いくつかのプロパティを持つクラスがあります。各プロパティを設定したら、アプリケーションの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");

    @終わり

このテクニックをあきらめるには近すぎると感じます。誰か提案はありますか?

4

2 に答える 2

3

Key-Value Observing(KVO)が必要なようです。

于 2013-03-21T08:08:23.583 に答える
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、必要なことを正確に行うために、4つのパラメータを持つマクロを作成できます

#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];
    }
}
于 2013-03-21T09:15:01.003 に答える