美文网首页swift 学习进阶
swift 进阶:懒加载 & 单例

swift 进阶:懒加载 & 单例

作者: 欧德尔丶胡 | 来源:发表于2021-02-27 17:23 被阅读0次

    swift 进阶之路:学习大纲

    1. Lazy 懒加载

    1.1 创建

    swift懒加载是使用Lazy进行修饰

    • 必须是var(可变存储属性),不可以是let(不可变属性),也不能是option(可选值)。
    class HTPerson {
        // 懒加载属性
        lazy var name: String = "ht"
    }
    
    
    • 初始时,没有值
    • 首次访问后,有值
    • 所以Lazy修饰的属性,具备延时加载功能。(首次访问时才加载

    1.2 大小

    • 懒加载属性大小,与本身属性大小不同
      swift中int(64位系统)原本8字节,但lazy修饰后,就变成16字节

      image

    1.3 懒加载的本质

    • 懒加载属性,创建时,是可选值。但是在首次访问(getter)时,进行初始赋值,返回非可选类型的值。

    • 懒加载是线程不安全的。 读写未加锁,多线程同时访问(getter)时,可能多次赋值

    Q: 为何lazy修饰的Int属性是16字节:

    • 因为lazy修饰的属性,会变成可选类型
      option: 可选类型。本质是枚举值类型
      包含some<Int>none两个枚举类型。其中none0x0。打印
    ![image](https://img.haomeiwen.com/i12857030/bbe04395faff43ee.png?imageMogr2/auto-orient/strip|imageView2/2/w/480)
    
    • 其中:none1字节some<Int>8字节。所以实际大小(size)为9字节
    • 对外遵循align8(8字节对齐)原则,系统会开辟16字节空间(8的倍数)来存储真实大小9字节数据
      align8原则:为了避免五花八门空间大小,增加系统读取数据困难性。所以统一8字节为一个单位,进行一段一段截取,提高读取效率。)

    lazy总结

    • lazy必须修饰var(可变类型)存储属性,
    • 必须有默认初始值,但初始值会延迟首次加载赋值
      (所以lazy修饰属性,叫延迟存储属性,也叫懒加载属性)
    • 延迟存储属性线程不安全的(可能多次赋值)
    • 延迟存储属性影响实例对象大小

    2. static 单例

    Swift单例:

    直接static创建,将init方法藏起来(private私有重写)。

    class HJPerson {
        // 创建单例对象
        static let sharedInstance = HJPerson()
        // 重写init方法,设为私有方法
        private init(){}
    }
    
    • swift源码查看swift_once,内部调用gcddispatch_once_f,创建单例线程安全(内部有锁,读写安全)。

    OC单例:
    使用gcd创建,使用父类alloc初始化,拦截alloc,任何方式实例化,返回的都是单例对象。

    @implementation HTPerson
    
    static HTPerson *sharedInstance = nil;
    
    + (instancetype)sharedInstance{
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            // 不使用alloc方法,而是调用[[super allocWithZone:NULL] init]
            // 重载allocWithZone基本的对象分配方法,所以要借用父类(NSObject)的功能处理底层内存分配
            // 此时不管外部使用设么方式创建对象,最终返回的都是单例对象
            sharedInstance = [[super allocWithZone:NULL] init] ;
        });
        return sharedInstance;
    }
    
    +(id)allocWithZone:(struct _NSZone *)zone {
        return [HTPerson sharedInstance] ;
    }
     
    -(id)copyWithZone:(NSZone *)zone {
        return [HTPerson sharedInstance] ;
    }
     
    -(id)mutablecopyWithZone:(NSZone *)zone {
        return [HTPerson sharedInstance] ;
    }
    
    @end
    

    参考:https://www.jianshu.com/p/4d8948a03e67

    相关文章

      网友评论

        本文标题:swift 进阶:懒加载 & 单例

        本文链接:https://www.haomeiwen.com/subject/vpsifltx.html