property的系統實現分析
我們在使用@property
這個快捷定義的時候,都沒怎麼注意系統是怎麼實現的,那麼我們來看看系統實現的,和我們自己寫的setter方法是否一致呢?
Strong
我們來分析一下最簡單的strong型別的實現。
@property (nonatomic, strong) NSString *str;
如果是我們自己寫setter方法大概是:
- (void)setStr:(NSString *)str {
_str = str;
}
如果是MRC的話,可能是這樣的:
- (void)setStr:(NSString *)str {
if (_str != str) {
[_str release];
_str = [str retain];
}
}
當然系統的方法是經過優化的,直接呼叫的C方法,所以這裡不再考慮MRC的寫法,直接來對比ARC的結果。
store strong
首先我們來看下objc是如何實現strong的,根據objc的原始碼可以知道,強引用是通過一個objc_storeStrong
的方法來實現的。其實現入下:
void objc_storeStrong(id *location, id obj)
{
id prev = *location;
if (obj == prev) {
return;
}
objc_retain(obj);
*location = obj;
objc_release(prev);
}
這和我們上面MRC的寫法類似,只不過是通過C方法來實現了retain和release。
轉換為C語言
大家都知道objc的方法其實都是通過send message的方式轉換為C語言呼叫的,所以一個基本的setter方法的最終結果應該是這樣的:
void setter(id self, SEL selector, NSString *str);
具體實現
根據反彙編結果,其中系統預設的實現彙編如下:
sub sp, sp, #0x30 ; 申請棧空間
stp x29, x30, [sp, #0x20]
add x29, sp, #0x20
adrp x8, 17
add x8, x8, #0xfc0
stur x0, [x29, #-0x8]
str x1, [sp, #0x10]
str x2, [sp, #0x8]
ldr x0, [sp, #0x8]
ldur x1, [x29, #-0x8] ; x1 = self
ldrsw x8, [x8] ; 偏移量
add x8, x1, x8 ; x8 = self + 偏移量
str x0, [sp]
mov x0, x8 ; x0 = x8
ldr x1, [sp] ; x1 = str
bl 0x1000bcad8 ; objc_storeStrong(self + 偏移量, str)
ldp x29, x30, [sp, #0x20]
add sp, sp, #0x30 ; 退棧
ret
翻譯為C語言大概就是這樣的:
void setStr(id self, SEL sel, NSString *str) {
objc_storeStrong(self + delta, str);
}
而我們自定義的setter方法
- (void)setStr:(NSString *)str {
_str = str;
}
的反彙編結果卻比系統的結果多出一些函式呼叫
sub sp, sp, #0x30 ; =0x30
stp x29, x30, [sp, #0x20]
add x29, sp, #0x20 ; =0x20
add x8, sp, #0x8 ; =0x8
mov x9, #0x0 ;
stur x0, [x29, #-0x8]
str x1, [sp, #0x10]
str x9, [sp, #0x8]
mov x0, x8
mov x1, x2
bl 0x104d14ad8 ; symbol stub for: objc_storeStrong
adrp x8, 17
add x8, x8, #0xfc8 ; =0xfc8
ldr x9, [sp, #0x8]
ldur x0, [x29, #-0x8]
ldrsw x8, [x8]
add x8, x0, x8
mov x0, x8
mov x1, x9
bl 0x104d14ad8 ; symbol stub for: objc_storeStrong
mov x8, #0x0
add x9, sp, #0x8 ; =0x8
mov x0, x9
mov x1, x8
bl 0x104d14ad8 ; symbol stub for: objc_storeStrong
ldp x29, x30, [sp, #0x20]
add sp, sp, #0x30 ; =0x30
ret
翻譯成C語言大概是這樣的:
void setStr(id self, SEL sel, NSString *str) {
id tmp = nil;
objc_storeStrong(&tmp, str);
objc_storeStrong(self + delta, tmp);
objc_storeString(&tmp, nil);
}
可以看到這裡多出一個臨時變數,而且即使編譯優化為-os
,也是同樣的結果。這裡不清楚為什麼會產生一次臨時變數,從結果上來看,是不如系統的預設行為的。
Weak
在objc的原始碼中,weak是通過objc_storeWeak
來實現的,這個方法的實現比較複雜,涉及到了全域性的弱引用表,這裡就不作介紹了。
同樣,我們來對比下系統預設實現的weak型別,和我們重寫的setter方法,從結果上來看也是產生了一個strong型別的臨時變數。
sub sp, sp, #0x40 ; =0x40
stp x29, x30, [sp, #0x30]
add x29, sp, #0x30 ; =0x30
adrp x8, 17
add x8, x8, #0xfd0 ; =0xfd0
stur x0, [x29, #-0x8]
stur x1, [x29, #-0x10]
str x2, [sp, #0x18]
ldr x0, [sp, #0x18]
ldur x1, [x29, #-0x8]
ldrsw x8, [x8]
add x8, x1, x8
str x0, [sp, #0x10]
mov x0, x8
ldr x1, [sp, #0x10]
bl 0x104f38ae4 ; symbol stub for: objc_storeWeak
str x0, [sp, #0x8]
ldp x29, x30, [sp, #0x30]
add sp, sp, #0x40 ; =0x40
ret
sub sp, sp, #0x30 ; =0x30
stp x29, x30, [sp, #0x20]
add x29, sp, #0x20 ; =0x20
add x8, sp, #0x8 ; =0x8
mov x9, #0x0
stur x0, [x29, #-0x8]
str x1, [sp, #0x10]
str x9, [sp, #0x8]
mov x0, x8
mov x1, x2
bl 0x1044d8ad8 ; symbol stub for: objc_storeStrong
adrp x8, 17
add x8, x8, #0xfc8 ; =0xfc8
ldr x9, [sp, #0x8]
ldur x0, [x29, #-0x8]
ldrsw x8, [x8]
add x8, x0, x8
mov x0, x8
mov x1, x9
bl 0x1044d8ae4 ; symbol stub for: objc_storeWeak
mov x8, #0x0
add x9, sp, #0x8 ; =0x8
str x0, [sp]
mov x0, x9
mov x1, x8
bl 0x1044d8ad8 ; symbol stub for: objc_storeStrong
ldp x29, x30, [sp, #0x20]
add sp, sp, #0x30 ; =0x30
ret
相關文章
- CSDN部落格分類系統的分析與實現
- Linux核心分析--系統呼叫實現程式碼分析(轉)Linux
- RequireJS結構分析,實現自己的模組載入系統UIJS
- linux核心檔案IO的系統呼叫實現分析(open)Linux
- 也用 C++ 實現 Property 功能 (轉)C++
- Linux系統呼叫詳解(實現機制分析)Linux
- 分散式系統選主場景分析及實現分散式
- 分散式系統限流演算法分析與實現分散式演算法
- 幫助系統的實現
- 分析系統查詢第一響應者的過程實現
- 入侵檢測系統分析及其在Linux下的實現(轉)Linux
- 用Descriptor來實現類級屬性(Property)
- 在C++中實現“屬性 (Property)” (轉)C++
- 雲控系統的實現原理
- 線上消費行為統計與分析系統設計和實現
- Vue-Property-Decorator原始碼分析Vue原始碼
- AOP實現系統告警
- Linux檔案系統的實現Linux
- Flutter 系統是如何實現ExpansionPanelList的Flutter
- PHP外掛系統的實現(一)PHP
- PHP外掛系統的實現(三):實現探測器PHP
- 實時日誌分析系統的基本架構架構
- 影片直播系統原始碼,非同步處理實現程式碼分析原始碼非同步
- 基於Linux系統的影片點播系統的實現(轉)Linux
- 現代分散式系統架構的權衡分析分散式架構
- 儲存系統實現-構建自己的儲存系統(一)
- 實現一個SSO系統
- PHP外掛系統的實現(四):實現註冊動作PHP
- PHP實現Google Oauth的登入系統PHPGoOAuth
- ServerSocket實現簡單的廣播系統Server
- 軟體系統的設計和實現
- .NET 實現的互動式 OA 系統
- IT系統的業務模型分析與系統建模模型
- 系統分析
- ERP/MES製造系統實施的效益分析
- 行業分析| OA系統中的實時通訊行業
- Python 基於 selenium 實現不同商城的商品價格差異分析系統Python
- 深入分析CRM系統對現代企業的作用