1 单例的优缺点
优点:
-
全局访问点:提供一个全局访问点,避免了重复创建实例的开销
-
节省资源:应用程序生命周期内只存在一个实例,不会频繁地创建和销毁对象,可以节省系统资源
-
数据共享:存储应用程序全局的状态信息或共享数据,方便不同模块之间的数据传递和共享
缺点:
-
维护困难:隐藏对象之间的依赖关系,使得代码难以理解和维护
-
扩展困难:没有抽象层,因此单例类的扩展有很大的困难
-
测试困难:单例对象的全局性和不可控性会增加单元测试的复杂度
-
性能问题:单例模式可能会导致性能下降或出现死锁等并发问题
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