iOS 单例设计模式

100 阅读1分钟

1 单例的优缺点

优点:

  1. 全局访问点:提供一个全局访问点,避免了重复创建实例的开销

  2. 节省资源:应用程序生命周期内只存在一个实例,不会频繁地创建和销毁对象,可以节省系统资源

  3. 数据共享:存储应用程序全局的状态信息或共享数据,方便不同模块之间的数据传递和共享

缺点:

  1. 维护困难:隐藏对象之间的依赖关系,使得代码难以理解和维护

  2. 扩展困难:没有抽象层,因此单例类的扩展有很大的困难

  3. 测试困难:单例对象的全局性和不可控性会增加单元测试的复杂度

  4. 性能问题:单例模式可能会导致性能下降或出现死锁等并发问题

2 单例中使用 NSMutableArray 要注意什么?

#import <Foundation/Foundation.h>

@interface MySingleton : NSObject

@property (atomic, strong) NSMutableArray *dataArray;

+ (instancetype)sharedInstance;

- (void)enumerateDataArrayUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;
- (void)modifyDataArrayWithBlock:(void (^)(NSMutableArray *dataArray))block;

@end



#import "MySingleton.h"

@implementation MySingleton

static MySingleton *sharedInstance = nil;

+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// 使用 dispatch_once 保证初始化只执行一次
- (instancetype)init {
    self = [super init];
    if (self) {
        // 初始化工作
        _dataArray = [NSMutableArray array];
    }
    return self;
}

// 确保分配内存时返回的是同一个单例对象
+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [super allocWithZone:zone];
            return sharedInstance;
        }
    }
    return nil; // 返回 nil 避免重复创建
}

// 返回自身,阻止对象被复制
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (void)enumerateDataArrayUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    if (!self.dataArray) {
        return;
    }
    
    @synchronized(self.dataArray) {
        [self.dataArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:block];
    }
}

- (void)modifyDataArrayWithBlock:(void (^)(NSMutableArray *dataArray))block {
    if (!self.dataArray) {
        return;
    }
    
    // 通过互斥锁 @synchronized 关键字来确保线程安全
    @synchronized(self.dataArray) {
        block(self.dataArray);
    }
}

@end