懒惰加载属性在swift中

Bre*_*and 37 swift

我试图围绕Swift语言.使用Objective-C在代码中构建视图时的常见模式是覆盖UI属性并延迟加载它们,如下所示:

@property(nonatomic, strong) UILabel *myLabel;

- (UILabel *)myLabel
{
     if (!_myLabel) {
         _myLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0f, 75.0f, 320.0f, 20.0f)];
        [_myLabel setFont:[UIFont subHeadlineFont]];
        [_myLabel setTextColor:[UIColor subHeadlineColor]];
        [_myLabel setText:@"Hello World"];
     }
     return _myLabel;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.view addSubview:self.myLabel];
}
Run Code Online (Sandbox Code Playgroud)

这允许UIElements的配置在其设置中自包含,但不会导致每次重新配置它们.

我们似乎无法访问Swift中的后备存储,并且@lazy关键字实际上没有相同的语义.

我很好奇是否有人在Swift中发现了一个类似的模式,它允许人们以一种整洁的语法方式将变量和常量的配置与它们的声明一起保存,每次都不会导致重新配置?

Chr*_*jær 71

我认为lazy用闭包初始化的属性可以工作:

lazy var myLabel: UILabel = {
    var temporaryLabel: UILabel = UILabel()
    ...
    return temporaryLabel
}()
Run Code Online (Sandbox Code Playgroud)

当我读到"The Swift Programming Language."(Checkerboard示例)时,闭包仅被评估一次).

  • 内部临时标签可以是一个让人,但显然没有任何不良后果. (5认同)
  • 惰性属性必须是`var`,不能是`let` (4认同)
  • 放下@符号 (4认同)
  • 闭包只执行一次. (2认同)
  • 评估关闭.闭包的类型为"() - > UILabel".但属性"myLabel"的类型为"UILabel".因此,当第一次需要myLabel时,需要对闭包进行评估,并将返回值分配给"myLabel". (2认同)

mat*_*att 6

class Thingy {
    init(){
        println("making a new Thingy")
    }
}

var thingy = {
    Thingy();
}()

println("\(self.thingy)")
println("\(self.thingy)")
Run Code Online (Sandbox Code Playgroud)

日志消息"制作一个新的Thingy"只出现一次,证明只创建了一个Thingy - 闭包仅被调用一次,即初始化此属性.这实际上就是你所描述的.您所要做的就是向闭包添加更多内容,以便为返回的对象配置它.

如果你创建了var @lazy并注释掉了这些println语句,那么就不会创建Thingy,从而证明懒惰能够完成它的目的; 但是,你可以省略这一点,因为你知道标签实际上总是在早期需要.点@lazy是为了防止盖曾经被称为除非吸气叫,但你总是会叫吸气所以这是在您的情况毫无意义.

  • @PhamHoan不,这没错.我们定义一个变量,其默认值是_calling_函数的结果.Apple正在定义一个变量,其默认值_is_是一个函数. (2认同)