你真的了解iOS怎么取屬性的嗎?

你真的了解iOS怎么取屬性的嗎?

本文來自CocoaChina粉絲FlyOceanFish投稿

如果iOS中談到取屬性,相信大家都會夸夸其談,不就是get方法嗎?或者大談kvc取屬性的機制。不得不說這些也是對的。這時大家可能就疑惑了,那你還要說啥的!!大家不妨想想,這些都是代碼層的實現,其實我們的代碼最終都會被編譯,然后加載到內存中,那你在內存中是怎么取到屬性的呢??對的我們討論就是它!

指針

如果說到內存,不知道大家會不會想到**指針**呢?這里簡單介紹一下,讓大家有個簡單的理解。如果理解不了的話,建議大家找一個C語言的教程,學一下指針。

指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另一個地方的值。由于通過地址能找到所需的變量單元,可以說,地址指向該變量單元。因此,將地址形象化的稱為“指針”。意思是通過它能找到以它為地址的內存單元。

  • *那到底什么是指針呢??

?類型 * 變量名

這就是聲明了一個指針變量

  • ?指針類型有什么作用呢?

比如:

1
int*?num;

指針變量的類型決定了通過這個指針找到變量的首地址以后,連續操作多少個字節空間

為什么會說連續操作多少個字節空間??主要是指針有算術運算加減,說白了就是指針的移動。

  • ?指針是int* 連續操作4個字節

  • 指針是double* 連續操作8個字節

比如:

1
2
int*?p?=?#
p++;

當指針+1的時候,這時候指針要移動1個單元,而不是1個字節!!

那到底這1個單元是多大呢?其實1個單元的大小就是指針類型的大小。這里是`int`型,所以移動了4個字節

-------------------------------------------------------------------------------------------

以上就是簡單給大家做了**指針**介紹,其實理解了指針,對于我們出現的一些野指針的bug、runtime源碼中的一些機制等等是有所幫助的。言歸正傳。接下來讓我看一道題,真正的去了解內存和指針的關系。

1
2
3
4
5
6
int?num1?=?10;
int?num?=?20;
int*?p?=?#
p++;
printf("%d
",*p);//打印為10,因為p++,指針已經移動了4個字節,下一個內存存儲10正好是4個字節

這里其實是前邊聲明了一個num1,正好是4個字節,所以就將10取出來了。(說白了就是內存中下一個連續的4個字節存的是什么取出來就是什么)

說了這么多都是指針和內存,建議大家搞明白以上內容再讀以下的內容,如果上邊都搞不明白的話,下邊有關iOS中runtime取屬性的內容有可能就會云里霧里。

iOS中成員變量與屬性

以下題目是sunnyxx習題中的一題,網上也有詳細的[答案](http://blog.csdn.net/shznt/article/details/50481819)。這里作者就簡述一下自己的理解,如果想看非常詳細的答案的話可以點擊上邊的鏈接。

下面代碼會? Compile Error / Runtime Crash / NSLog…?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@interface?Sark?:?NSObject
@property?(nonatomic,?copy)?NSString?*name;
@end
@implementation?Sark
-?(void)speak
{
????NSLog(@"my?name?is?%@",?self.name);
}
@end
@interface?Test?:?NSObject
@end
@implementation?Test
-?(instancetype)init
{
????self?=?[super?init];
????if?(self)?{
????????id?cls?=?[Sark?class];
????????void?*obj?=?&cls;
????????[(__bridge?id)obj?speak];
????}
????return?self;
}
@end
int?main(int?argc,?const?char?*?argv[])?{
????@autoreleasepool?{
????????[[Test?alloc]?init];
????}
????return?0;

}

答案:代碼正常輸出,輸出結果為:

2014-11-07 14:08:25.698 Test[1097:57255] my name is

  • ?為什么能夠正常運行,并調用到speak方法?

計算機將我們的`Sark`類信息通過

`id cls = [Sark class];`這一行加載到內存中,并且取得了`cls`變量。這個時候其實我們只要知道`cls`這個變量的地址就行了,其實相當于類的對象的地址。`void *obj = &cls;`這句話就讓我們獲得了對象的地址。(平時我們`new`對象的時候就干了兩件事:1、申請內存;2、獲取內存的地址(對象變量的地址就是內存的地址),這里的對象與我們`new`出來的對象有所不同。但是雖然不是new對象,iOS中`Class`對象已經存儲了我們需要的東西。比如有關變量的內存**偏移**、方法等等所有的信息)接下來可以干我們想干的任何事情了。

>iOS中`Class`中存儲了我們想要的東西,這一塊的知識要上升到了runtime的源碼,上邊給到的鏈接中有詳細介紹。其實大家想想編譯完之后肯定得有一個類或者其他東西存儲著有關內存等等相關的信息的。

  • 為什么self.name會輸出?

我們程序在編譯之后其實就是一堆的匯編指令,匯編操作的就是**內存地址**。所以當我們程序運行的時候都是**寄存器**一條條的執行匯編指令。其實執行匯編指令最重要的就是變量、方法、對象等等的一大堆地址,因為寄存器有限,所以會把有限的數據從內存中加載到寄存器。所以總得來說是操作寄存器的地址和內存地址。如果沒有地址那怎么知道執行什么呢?所以只要有地址了就好辦了。

指令如下圖:

image.png

?

變量對應于runtime的objc_ivar代碼如下:

?

1
2
3
4
5
6
7
8
struct?objc_ivar?{
????char?*ivar_name??????????????????????????????????????????OBJC2_UNAVAILABLE;
????char?*ivar_type??????????????????????????????????????????OBJC2_UNAVAILABLE;
????int?ivar_offset??????????????????????????????????????????OBJC2_UNAVAILABLE;
#ifdef?__LP64__
????int?space????????????????????????????????????????????????OBJC2_UNAVAILABLE;
#endif
}

其中?`ivar_offset`就是變量的地址偏移字節。

變量地址=對象地址 + 基類大小 + ivar偏移字節

到這里再結合我上邊指針的鋪墊相信大家應該明白了為什么為什self.name會輸出吧。

其實通過這里我們也知道了其實iOS中取對象就是指針的偏移。

1
2
3
4
5
6
Student?*student?=?[[Student?alloc]?init];
??Ivar?age_ivar?=?class_getInstanceVariable(object_getClass(student),?"age");
??int?*age_pointer?=?(int?*)((__bridge?void?*)(student)?+?ivar_getOffset(age_ivar));
??NSLog(@"age?ivar?offset?=?%td",?ivar_getOffset(age_ivar));
??*age_pointer?=?10;

轉載于:https://www.cnblogs.com/ruixin-jia/p/8175871.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539715.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539715.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539715.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Oracle表的并行度

查看dba_tables數據字典時,可以發現有“DEGREE”字段,這個字段表示的就是數據表的并行度。這個參數的設置,關系著數據庫的I/O,以及sql的執行效率。并行度的優點就是能夠最大限度的利用機器的多個cpu資源,是多個cpu同時…

mysql 臨時表 限制_Mysql臨時表

當你創建臨時表的時候,你可以使用temporary關鍵字。如:create temporary table tmp_table(name varchar(10) not null,passwd char(6) not null)‘或CREATE TEMPORARY TABLE IF NOT EXISTS sp_output_tmp ENGINE MEMORY SELECT …from … where IDcurre…

10年老兵給程序員的10條建議!

2019獨角獸企業重金招聘Python工程師標準>>> 程序員雖然薪資待遇好,但是也得付出努力,技術好才行。特別是對于剛剛進入編程工作的新手程序員和正在學習編程的同學來說,一寫代碼就報錯,出bug。作為一個工作了10年的老兵…

視圖和表的區別和聯系

區別: 1、視圖是已經編譯好的sql語句。而表不是 2、視圖沒有實際的物理記錄。而表有。 3、表是內容,視圖是窗口 4、表只用物理空間而視圖不占用物理空間,視圖只是邏輯概念的存在,表可以及時四對它進行修改&#xf…

mysql binlog日志三種格式_MySQL binlog三種格式詳細介紹

查看當前數據庫binlog日志格式:show global variables like %binlog_format%;一、三種格式介紹1.1 STATEMENT該格式下每一條會修改數據的sql都會記錄在binlog中;優點:不需要記錄每一行的變化,減少了binlog日志量,節約了…

2017阿里技術年度精選(全)

2019獨角獸企業重金招聘Python工程師標準>>> 2017年,在技術發展的歷史上,一定是個特別的一年:柯潔與AlphaGo的驚世大戰,無人咖啡店開放體驗,AI設計師“魯班”橫空出世、三年投入千億的達摩院正式成立…… 這…

查詢Oracle正在執行的sql語句,鎖表,解鎖

原文出處:http://blog.csdn.net/jlds123/article/details/6572559 ----------------------- --查詢Oracle正在執行的sql語句及執行該語句的用戶 [sql] view plaincopy SELECT b.sid oracleID, b.username 登錄Oracle用戶名, b.serial#, …

xampp for mac mysql_xampp for mac下載-Xampp Mac版下載 V7.3.2-PC6蘋果網

Xampp for mac是目前時下最流行的PHP開發環境,XAMPP是完全免費且易于安裝的Apache發行版,其中包含MySQL、PHP和Perl。XAMPP開放源碼包的設置讓安裝和使用出奇容易。整合型的Apache套件。XAMPP包括Apache、MySQL、PHP、PERL,直接解壓縮&#x…

15.2. important

<para><important>Text goes here.</important></para>重要Text goes here.原文出處&#xff1a;Netkiller 系列 手札 本文作者&#xff1a;陳景峯 轉載請與作者聯系&#xff0c;同時請務必標明文章原始出處和作者信息及本聲明。

查看表的創建時間

select OWNER,OBJECT_NAME,CREATED from dba_objects where OBJECT_NAME表名 CREATED 是表的創建時間 查詢 dba_objects 表需要dba權限

linux python2.7 scipy_scipy.sparse.linalg.sp為Linux系統上的大型稀疏矩陣解決了令人驚訝的行為...

我正在計算一個線性系統Ax b的解決方案&#xff0c;其中A具有一個大的(通常200,000行和相關的密集矩陣的列)稀疏矩陣和ba稀疏矩陣&#xff0c;大約100列。當我在Windows系統上運行代碼(Python2.7&#xff0c;scipy0.14.0)時&#xff0c;以下命令fromscipy.sparse.linalgimport…

簡簡單單的代碼讓你輕松學會 動態代理

原文出處&#xff1a;http://weixiaolu.iteye.com/blog/1477774 -------------------------------------------------------------------------- 簡簡單單的代碼讓你輕松學會動態代理 前言&#xff1a; 最近一直在分析hadoop的RPC機制。在hadoop中&#xff0c;DataNode和Na…

python變量和字符_Python變量和字符串

我需要知道Python中的變量是字符串(名稱)還是數字。我想檢查圖的度數&#xff0c;但是我需要知道“I”迭代器是字符串內部的一個數字還是字符串內的一個名稱&#xff0c;在末尾顯示了圖的度數。在這個代碼有什么問題嗎&#xff1f;在import csv, sysimport networkx as nxdef m…

Adobe軟件打開后設置默認頁面方式和默認鼠標方式

PDF文件打開后是默認顯示&#xff0c;與顯示器比例不協調&#xff0c;或大或小&#xff0c;總是需要手動調節閱讀方式&#xff0c;解決方法如下&#xff1a; Adobe軟件中可以設置默認頁面方式&#xff0c;具體步驟如下&#xff1a; 編輯 (Edit)-首選項(Preferences)-輔助工具…

CSS深入理解學習筆記之vertical-align

1、vertical-align基本認識 支持的屬性值&#xff1a; ①線類&#xff1a;baseline&#xff08;默認&#xff09;&#xff0c;top&#xff0c;middle&#xff0c;bottom ②文本類&#xff1a;text-top&#xff0c;text-bottom ③上標下標類&#xff1a;sub&#xff0c;super ④…

Java NIO原理 圖文分析及代碼實現

原文出處&#xff1a;http://weixiaolu.iteye.com/blog/1479656 ---------------------------------------------------------------------- Java NIO原理圖文分析及代碼實現 前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol &#xff0c;遠程過程調用協議&am…

威綸通觸摸屏與mysql_威綸觸摸屏應用實例 以及威綸通觸摸屏配方組合

在生產車間&#xff0c;每臺設備運作起來都會有各自的組合參數&#xff0c;每臺設備運作的時候產生的數據即構成配方表&#xff0c;每張配方表內可建立多組配方數據&#xff0c;這些多臺機器的配方數據都可儲存在人機里&#xff0c;以供控制器(PLC)執行相對應的任務。從“包裝機…

分析師視角:2018年的數據中心3大預測

向數字業務平臺的遷移促使基礎設施和運營(I&O)領導者必須重新去思考他們的數據中心策略。像人工智能這樣的數字業務平臺&#xff0c;包括機器學習(ML)、深度神經網絡(DNN)和物聯網&#xff0c;對IT基礎設施有敏捷和可伸縮性等方面的計算需求。在2018年&#xff0c;I&O領…

大數據實時處理:百分點實時計算架構和算法

原文&#xff1a;http://www.oschina.net/question/1459174_145255 百分點官網&#xff1a;http://www.baifendian.com/ ------------------以下正文---------------------- 當今時代&#xff0c;數據不再昂貴&#xff0c;但從海量數據中獲取價值變得昂貴&#xff0c;而要及時…

ELK 日志處理開發指南

ELK 是 Elastic 公司出品的開源實時日志處理與分析解決方案&#xff0c;ELK 分別代表分布式搜索引擎 Elasticsearch、日志采集與解析工具 Logstash、日志可視化分析工具Kibana&#xff0c;具有配置方式靈活、集群可線性擴展、日志實時導入、檢索性能高效、可視化分析方便等優點…