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;
}
FEATURED TAGS
iOS
OC
C
Xcode
MIMEType
屏幕旋转
Mac
工具
SQLite3
重命名
证书+内购
Pod
像素
pch
支付协议税务
APP转让
审核
银行卡格式化
git
描述文件
命令行
沙盒日志
i386
x86_64
控制台log
xcode10&iOS12
正则
textfield
输入限制
真机支持
封面尺寸
SDWebImage
Ruby
RVM
渐变色
jekyll
水印
富文本
标签
M3U8
动、静态库
异步上传
Url编码解码
AlertController
保活
pod报错
特定UI横竖屏
Launch版本号
ijkplayer
适配
手势
截图
网络和信号
礼物缓存
手绘礼物
UIPickerView
文件权限
键盘和菜单
耗时卡顿
国际化
Paypal
AWSS3
npm、Node
控制台
warning
扩展
防盗链
动画
分析
CallKit
侧滑
重置根控制器
播放器
裁剪
日志
bugly
uniapp
Swift
文字翻转
跨域
WebClip
网络请求
地图导航
ZSH
SPM
Vapor
导航
验证码
杀进程
Ubuntu
Android
JWT
vue
html-js
style-class
ssh
PHP
jks
css
Runtime
tree
uniCloud
圆角
flex
block
图形验证码
gtm
share
Combine
nvm
github
存储
总结