• 单例模式 & Init(allocWithZone:)


    一、Init

    在分配内存后,子类通过该实例方法,实例化类的新对象。

    1、init消息需要在同一行复合alloc方法使用,如SomeClass *obj = [[SomeClass alloc] init];

    2、方法返回值可能为nil,比如在没有相机的设备上新建相机对象就会返回nil。为保证你的创建过程的容错性,因此规范的写法如下:

    - (instancetype)init {
        if (self = [super init]) {
            // Initialize self
        }
        return self;
    }

    3、alloc和allocWithZone:方法,实例化一个isa对象变量,isa指向描述类的数据结构,内存中对象的其它变量初始化为0。alloc调用allocWithZone:方法,方法参数memory zones已不再使用。

    在该方法后,必须调用init方法,完成对象初始化过程。

    4、调用init方法前,对象指针不可用称为悬挂指针。调用init后,对象地址会发生改变,对象所在内存空间可以使用。

    二、单例模式

    单例提供全局可访问且共享的对象实例。通过自定义单例构造方法的方式,提供统一获取贯穿app的资源和服务,例如音频播放声音、网络管理对象发起HTTP请求。

    在OC中,你通过dispatch_once方法包裹实例化对象方法,以确保创建唯一的单例对象。在app的生命周期内,dispatch_once中的block有且仅执行一次。

    单例对象工厂方法如下:

    static SomeClass *sharedInstance = nil; // 静态变量
    
    + (instancetype)sharedInstance {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _sharedInstance = [[SomeClass alloc] init];
        });
        return _sharedInstance;
    }  

    三、单例问题

    问题:如果不通过sharedInstance构造实例对象,而通过init,不就违反单例模式的设计了吗?

    解决方案:由于init方法调用前,必定调用alloc和allocWithZone:方法,且alloc调用allocWithZone:方法,所以重写allocWithZone:方法,就可以保证不管通过什么方式创建的实例,都是同一个。

    新增代码如下:

    +(instancetype)allocWithZone:(struct _NSZone *)zone{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [super allocWithZone:zone];
        });
        return instance;
    }

    四、最后说明

    可以通过重写description方法,来确认是否是同一个对象,代码如下:

    -(NSString *)description{
        return [NSString stringWithFormat:@"< %p > name = %@, myObj = %p, arry = %p, mutable = %p", self, self.name, self.myObj, self.arry self.mutableArr];
    
    }
  • 相关阅读:
    TensorFlow conv2d实现卷积
    tensorflow max_pool(最大池化)应用
    tensorflow Relu激活函数
    tensorflow Sigmoid 应用
    tensorflow softmax应用
    并发和并行的区别
    eclipse常用快捷键即项目操作
    zookeeper学习一
    TCP的三次握手与四次挥手
    python编码问题unicode&str
  • 原文地址:https://www.cnblogs.com/zhouyi-ios/p/5066465.html
Copyright © 2020-2023  润新知