20241210补充:swift单例
1.快捷简单
public static let shared: LyNetwork = .init()
private init() {
// 私有初始化方法,防止外部直接初始化
}
2.冗余
static let shared: LyNetwork = {
// 先定义instance为可选类型
var instance: LyNetwork?
let queue = DispatchQueue(label: "com.lynetwork.singleton")
queue.sync {
// 在闭包内安全地初始化instance
instance = LyNetwork()
}
// 使用可选绑定确保instance有值后再返回,如果没有值会触发运行时错误,不过在正常逻辑下不会出现这种情况,因为闭包内会进行初始化
guard let unwrappedInstance = instance else {
fatalError("Singleton instance not initialized")
}
return unwrappedInstance
}()
private init() {
// 私有初始化方法,防止外部直接初始化
/* swift 中不允许使用 dispatch_once
var onceToken: dispatch_once_t = 0
var instance: LyNetwork?
dispatch_once(&onceToken, {
instance = LyNetwork()
})
*/
}
- 稍复杂的实现:使用了一个闭包和调度队列来初始化单例实例,代码相对复杂。
- 理论上的线程控制:使用 DispatchQueue 进行同步操作,目的是确保单例实例的初始化是线程安全的。不过在 Swift 中,静态常量本身已经保证了线程安全,这里的调度队列使用略显冗余。
- 延迟初始化的错觉:虽然代码看起来像是在控制初始化时机,但由于整个闭包在类加载时就会执行,实际上仍然是立即初始化,并非真正的延迟初始化。 错误处理:使用 guard let 进行可选绑定,如果 instance 为 nil 会触发 fatalError,不过在正常情况下这种情况不会发生。
AI总结
- 方式二这种实现方式在 Swift 中并不常见,因为它没有充分利用 Swift 语言本身的特性。如果是从 Objective - C 迁移过来的代码,可能会保留这种传统的线程安全初始化思路。但在纯 Swift 项目中,建议采用更简洁的方式。
实例0
.m
static YBRechargeType *chargeManeger = nil;
+(instancetype)chargeManeger {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
chargeManeger = [[super allocWithZone:NULL]init];
});
return chargeManeger;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone {
return [self chargeManeger];
}
实例1
UserContext.h头文件:
#import
@interface UserContext : NSObject <NSCopying>
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *email;
//单例 类方法
+(id)shareUserContext;
@end
UserContext.m实现文件:
#import "UserContext.h"
//单例对象
static UserContext *sigletonInstance=nil;
@implementation UserContext
//生成单例对象
+(id)shareUserContext{
@synchronized(self){
if (sigletonInstance==nil) {
sigletonInstance=[[[self class] alloc]init];
}
}
return sigletonInstance;
}
//下面的方法确保只有一个实例对象
+(id)allocWithZone: (NSZone *)zone{
if (sigletonInstance==nil) {
sigletonInstance=[super allocWithZone:zone];
}
return sigletonInstance;
}
-(id)copyWithZone: (NSZone *)zone
{
return sigletonInstance;
}
-(id)retain
{
return sigletonInstance;
}
-(oneway void)release
{
}
-(id)autorelease
{
return sigletonInstance;
}
-(NSUInteger)retainCount
{
return UINT_MAX;
}
@end
main.m测试代码:
#import
#import "UserContext.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
UserContext *userContext1=[UserContext shareUserContext];
UserContext *userContext2=[UserContext shareUserContext];
UserContext *userContext3=[[UserContext alloc]init];
UserContext *userContext4=[userContext3 copy];
[userContext1 release];
[userContext1 release];
[userContext1 release];
[userContext1 release];
NSLog(@" ");
}
return 0;
}