15

REMenu libコードを調べていたところ、vars が({ ... });として宣言されていることがわかりました。.. 遅延評価されたコードの「閉鎖」のように見えます.. わかりません.. 誰か説明してくれませんか?

self.menuWrapperView = ({
        UIView *view = [[UIView alloc] init];
        view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        if (!self.liveBlur || !REUIKitIsFlatMode()) {
            view.layer.shadowColor = self.shadowColor.CGColor;
            view.layer.shadowOffset = self.shadowOffset;
            view.layer.shadowOpacity = self.shadowOpacity;
            view.layer.shadowRadius = self.shadowRadius;
            view.layer.shouldRasterize = YES;
            view.layer.rasterizationScale = [UIScreen mainScreen].scale;
        }
        view;
    });

    self.toolbar = ({
        UIToolbar *toolbar = [[UIToolbar alloc] init];
        toolbar.barStyle = self.liveBlurBackgroundStyle;
        if ([toolbar respondsToSelector:@selector(setBarTintColor:)])
            [toolbar performSelector:@selector(setBarTintColor:) withObject:self.liveBlurTintColor];
        toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        toolbar;
    });
4

1 に答える 1

22

これは、"<a href="http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs" rel="nofollow noreferrer" と呼ばれる GNU (非標準) C 言語拡張です。 >ステートメント表現」。この構文は、gcc、clang、およびその他のいくつかのコンパイラでサポートされています。

基本的に、任意のブロックを単一の式として扱うことができ、その値はブロック内の最後のステートメントの値です。

この拡張機能は、主にマクロ定義で役立ちます。私の意見では、質問で引用したコード ( のshowFromRect:inView:メソッドから) は、ステートメント式を使用しないREMenu.m方がよいでしょう。代わりに、これらのステートメント式のコードを個別のメソッドに分割する必要があります。例えば:

    self.menuWrapperView = [self newMenuWrapperView];
    self.toolbar = [self newToolbar];

...

- (UIView *)newMenuWrapperView {
    UIView *view = [[UIView alloc] init];
    view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    if (!self.liveBlur || !REUIKitIsFlatMode()) {
        view.layer.shadowColor = self.shadowColor.CGColor;
        view.layer.shadowOffset = self.shadowOffset;
        view.layer.shadowOpacity = self.shadowOpacity;
        view.layer.shadowRadius = self.shadowRadius;
        view.layer.shouldRasterize = YES;
        view.layer.rasterizationScale = [UIScreen mainScreen].scale;
    }
    return view;
}

- (UIToolbar *)newToolbar {
    UIToolbar *toolbar = [[UIToolbar alloc] init];
    toolbar.barStyle = self.liveBlurBackgroundStyle;
    if ([toolbar respondsToSelector:@selector(setBarTintColor:)])
        [toolbar performSelector:@selector(setBarTintColor:) withObject:self.liveBlurTintColor];
    toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    return toolbar;
}
于 2013-11-01T17:35:35.040 に答える