Objective-C使用({...})声明变量

seu*_*ner 15 objective-c ios

我正在查看REMenu lib代码,并看到vars被声明为wiht ({...}); ..看起来像'封闭'到懒惰的评估代码..我不知道..有人可以解释一下吗?

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;
    });
Run Code Online (Sandbox Code Playgroud)

rob*_*off 22

这是一个名为" 语句表达式 " 的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;
}
Run Code Online (Sandbox Code Playgroud)

  • @robmayoff我主要同意你的编辑.但问题是,许多观点实际上是其他观点的集合,应该只是每个观点的一个实例.这些实例是在封装视图的实例化时创建的,它们的生命周期与容器紧密绑定.因此,"工厂喜欢"的方法并不真正有价值.可以使用延迟初始化(即首次执行getter),但这只会使实例化相对不确定.将所有视图配置代码保存在-configureSubviews方法中似乎很自然. (3认同)
  • 我很努力不喜欢这个,但它在我身上不断增长.@seufagner对 - 它实际上说*_menuWrapperView ivar由这个自包含的代码块初始化,不多也不少*.它肯定会使重构更容易(只需抓取赋值+整个范围,剪切...滚动..粘贴).它也非常易读.尾随的`view;`看起来有点奇怪,但我敢打赌编译器如果省略它会大肆抱怨. (2认同)
  • @bbum我们已经有了一个有效地说"*_menuWrapperView ivar由这个自包含的代码块初始化的语法,不多也不少.*"请参阅我的更新.也许如果语句表达式引用了封闭函数中定义的许多变量,则使用是合理的.在这种情况下,它只引用`self`,但你必须检查代码以发现,(在我看来)这使得语句表达式的使用严格地比函数调用更糟糕. (2认同)