zoukankan      html  css  js  c++  java
  • Swift Lazy计算属性的线程安全分析

    一、代码示例

    //
    //  ViewController.swift
    //  LazyTest
    //
    //  Created by lilun.ios on 2021/7/30.
    //
    
    import UIKit
    
    class ViewController: UIViewController {
        
        lazy var profileImageView: UIImageView = {
    
            let imageView = UIImageView(image: #imageLiteral(resourceName: "page1"))
            imageView.translatesAutoresizingMaskIntoConstraints = false
            imageView.contentMode = .scaleAspectFit
            return imageView
    
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            self.view.addSubview(self.profileImageView)
        }
    
    
    }
    profileImageView 变量是不是线程安全的呢?

    二、代码分析

    lazy修饰的变量是在第一次访问的时候初始化的,如果多线程访问这个Lazy变量,将会导致不可预知的结果
    有可能不同线程生成不同的lazy变量
    有可能一个线程初始化还没完成,另外一个线程就返回了这个变量
    反汇编这个变量getter的实现,判断这个变量是不是为空没有加锁,因此多线程访问下可能出现问题
    int _$s8LazyTest14ViewControllerC012profileImageC0So07UIImageC0Cvg() {
        var_58 = r13;
        memset(&var_8, 0x0, 0x8);
        memset(&var_28, 0x0, 0x8);
        memset(&var_48, 0x0, 0x8);
        swift_beginAccess(var_58 + *direct field offset for LazyTest.ViewController.($__lazy_storage_$_profileImageView in _45D895C0736D9EBC78CE118C3607CFFF) : __C.UIImageView?, &var_20, 0x20, 0x0);
        rsi = *(var_58 + rdx);
        var_78 = rsi;
        [rsi retain];
        swift_endAccess(&var_20);
        if (var_78 != 0x0) {
                var_90 = var_78;
        }
        else {
                rax = closure #1 ();
                var_98 = rax;
                [rax retain];
                swift_beginAccess(var_58 + *direct field offset for LazyTest.ViewController.($__lazy_storage_$_profileImageView in _45D895C0736D9EBC78CE118C3607CFFF) : __C.UIImageView?, &var_40, 0x21, 0x0, &var_40);
                rdx = *(var_58 + rsi);
                *(var_58 + rsi) = var_98;
                [rdx release];
                swift_endAccess(&var_40);
                var_90 = var_98;
        }
        rax = var_90;
        return rax;
    }

  • 相关阅读:
    HDU 1019 Least Common Multiple GCD
    HDU 1263 水果 结构体排序
    HDU 1256 画8 模拟题
    HDU 2058 The sum problem 数学题
    VC6.0开发OCX按钮控件
    利用压缩软件制作插件安装包
    vs生成的exe程序和相关dll打包
    vs2010开发activex(MFC)控件/ie插件(一)
    vs2010开发activex(MFC)控件/ie插件(二):js传参数
    vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/15081030.html
Copyright © 2011-2022 走看看