1. Lazy 懶加載
1.1 創(chuàng)建
swift
中懶加載
是使用Lazy
進(jìn)行修飾
- 必須是
var
(可變存儲屬性),不可以是let
(不可變屬性),也不能是option
(可選值)。
class HTPerson {
// 懶加載屬性
lazy var name: String = "ht"
}
初始
時(shí),沒有值
。
首次訪問
后,有值
- 所以
Lazy
修飾的屬性,具備延時(shí)加載
功能。(首次訪問
時(shí)才加載
)
1.2 大小
-
懶加載屬性
的大小
,與本身屬性
大小不同
:
swift中int
(64位系統(tǒng))原本8字節(jié)
,但lazy修飾后
,就變成16字節(jié)
image
1.3 懶加載的本質(zhì)
懶加載屬性,創(chuàng)建時(shí),是
可選值
。但是在首次訪問(getter)時(shí),進(jìn)行初始賦值,返回非可選類型的值。懶加載是
線程不安全
的。讀寫未加鎖
,多線程同時(shí)訪問(getter)時(shí),可能多次賦值
Q: 為何lazy修飾的Int屬性是16字節(jié):
- 因?yàn)?code>lazy修飾的屬性,會變成
可選類型
。
(option
: 可選類型。本質(zhì)是枚舉
,值類型
)
包含some<Int>
和none
兩個(gè)枚舉類型。其中none
是0x0
。打印
- 其中:
none
占1字節(jié)
,some<Int>
占8字節(jié)
。所以實(shí)際大小
(size)為9字節(jié)
。- 對外遵循
align8
(8字節(jié)對齊)原則,系統(tǒng)
會開辟16字節(jié)空間
(8的倍數(shù))來存儲真實(shí)大小
為9字節(jié)
的數(shù)據(jù)
(align8原則
:為了避免五花八門
的空間大小
,增加系統(tǒng)讀取數(shù)據(jù)
的困難性
。所以統(tǒng)一
以8字節(jié)
為一個(gè)單位
,進(jìn)行一段一段
的截取
,提高讀取效率
。)
lazy總結(jié)
lazy
必須修飾var
(可變
類型)存儲
屬性,- 必須有
默認(rèn)初始值
,但初始值會延遲
到首次加載
時(shí)賦值
。
(所以lazy修飾
的屬性
,叫延遲存儲屬性
,也叫懶加載
屬性)延遲存儲屬性
是線程不安全
的(可能多次賦值)延遲存儲屬性
影響實(shí)例對象
的大小
2. static 單例
Swift單例:
直接static創(chuàng)建,將init方法藏起來(private私有重寫)。
class HJPerson {
// 創(chuàng)建單例對象
static let sharedInstance = HJPerson()
// 重寫init方法,設(shè)為私有方法
private init(){}
}
-
swift源碼
查看swift_once
,內(nèi)部調(diào)用gcd
的dispatch_once_f
,創(chuàng)建單例
,線程安全
(內(nèi)部有鎖,讀寫安全)。
OC單例:
使用gcd創(chuàng)建,使用父類alloc初始化,攔截alloc,任何方式實(shí)例化,返回的都是單例對象。
@implementation HTPerson
static HTPerson *sharedInstance = nil;
+ (instancetype)sharedInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 不使用alloc方法,而是調(diào)用[[super allocWithZone:NULL] init]
// 重載allocWithZone基本的對象分配方法,所以要借用父類(NSObject)的功能處理底層內(nèi)存分配
// 此時(shí)不管外部使用設(shè)么方式創(chuàng)建對象,最終返回的都是單例對象
sharedInstance = [[super allocWithZone:NULL] init] ;
});
return sharedInstance;
}
+(id)allocWithZone:(struct _NSZone *)zone {
return [HTPerson sharedInstance] ;
}
-(id)copyWithZone:(NSZone *)zone {
return [HTPerson sharedInstance] ;
}
-(id)mutablecopyWithZone:(NSZone *)zone {
return [HTPerson sharedInstance] ;
}
@end