真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

iOS如何獲取屬性

這篇文章主要介紹了iOS如何獲取屬性,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設、做網(wǎng)站與策劃設計,涉縣網(wǎng)站建設哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設十載,網(wǎng)設計領(lǐng)域的專業(yè)建站公司;建站業(yè)務涵蓋:涉縣等地區(qū)。涉縣做網(wǎng)站價格咨詢:028-86922220

指針

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

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

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

 類型 * 變量名

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

 指針類型有什么作用呢?

比如:

int* num;

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

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

  • 指針是int* 連續(xù)操作4個字節(jié)

  • 指針是double* 連續(xù)操作8個字節(jié)

比如

int* p = #
p++;

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

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

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

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

int num1 = 10;
int num = 20;
int* p = #
p++;
printf("%d
",*p);//打印為10,因為p++,指針已經(jīng)移動了4個字節(jié),下一個內(nèi)存存儲10正好是4個字節(jié)

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

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

iOS中成員變量與屬性

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

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

@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;
}

答案:代碼正常輸出,輸出結(jié)果為:

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

 為什么能夠正常運行,并調(diào)用到speak方法?

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

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

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

為什么self.name會輸出?

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

指令如下圖:

iOS如何獲取屬性

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

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`就是變量的地址偏移字節(jié)。

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

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

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

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;
 NSLog(@"%@", student);

感謝你能夠認真閱讀完這篇文章,希望小編分享的“iOS如何獲取屬性”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!


文章名稱:iOS如何獲取屬性
轉(zhuǎn)載注明:http://weahome.cn/article/pgpecc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部