iOS修改宣告為readonly的屬性值

2021-09-08 19:31:32 字數 2491 閱讀 4297

本文討論的是,對於類中宣告為 readonly 的屬性值,我們就不可以修改其值了麼?如何可以,那麼如何修改呢?

為了便於說明,定義乙個 aclstudent 的類:

aclstudent.h

@inte***ce

aclstudent : nsobject

@property (nonatomic, assign, readonly) nsinteger studentid;

@property (nonatomic, copy, readonly) nsstring *firstname;

@property (nonatomic, copy, readonly) nsstring *lastname;

- (instancetype)initwithstudentid:(nsinteger)studentid firstname:(nsstring *)firstname lastname:(nsstring *)lastname;

@end

--------------------------aclstudent.m

@implementation aclstudent

- (instancetype)initwithstudentid:(nsinteger)studentid firstname:(nsstring *)firstname lastname:(nsstring *)lastname

return

self;

}@end

接下來定義乙個 aclstudent 類的物件:

aclstudent *student = [[aclstudent alloc] initwithstudentid:1 firstname:@"carya" lastname:@"liu"];

nslog(@"student firstname: %@", student.firstname);

現在我們考慮的就是如何修改 student 物件的 firstname 屬性值為 @"qiu"。

如果直接呼叫 firstname 的 setter 方法, student.firstname = @"qiu", 那麼就直接報錯,提示不能夠給宣告為 readonly 的屬性賦值。那麼使用 kvc 呢?

[student setvalue:@"qiu"forkey:nsstringfromselector(@selector(firstname))];

nslog(@"student firstname after changed: %@", student.firstname);

執行,發現屬性值被成功修改。哈哈,那麼現在來看看 kvc 為什麼能夠修改該屬性值呢?看看文件 accessor search implementation details 。

當使用 setvalue:forkey: 來設定物件的屬性時,會以下面的優先順序來尋找對應的 key :

訊息接收物件會查詢是否存在滿足 set

: 格式的訪問方法。

如果不存在滿足條件的訪問方法,且訊息接收物件的類方法 + (bool)accessinstancevariablesdirectly 返回 yes,那麼該物件會以 _, _is, , is的順序查詢是否存在對應的key。

如果存在對應的訪問方法或者找到對應的例項變數,那麼就會改變該 key 所對應的值 value。必要的話,value 所對應的值會從物件中解析出來,如 representing non-object values 所描述的那樣。

如果沒有找到對應的訪問方法或者例項變數,那麼該訊息物件的 setvalue:forundefinedkey: 將會呼叫。

對於上述第2點說明一下,如果我們不想讓 setvalue:forkey: 方法改變物件的屬性值,那麼重寫其類方法 +(bool)accessinstancevariablesdirectly 返回 no (該方法預設返回 yes,即在不存在滿足條件的訪問方法時,允許直接訪問屬性對應的例項變數);在搜尋例項變數時,會首先檢查帶下劃線的例項變數,然後檢查不帶下劃線的例項變數。

對於上述第3點舉例說明,如果修改 student 物件的屬性 nsinteger studentid , 注意其是 nsinteger 型別,我們在呼叫 setvalue:forkey: 方法時可以像這樣

[student setvalue:@(20) forkey:nsstringfromselector(@selector(studentid))];

傳入乙個 nsnumber 物件也可以,objective-c 會處理好一切。

對於上面的示例,使用 setvalue:forkey: 實際修改的是 student 例項中 _firstname 例項變數的值。不要忘記,我們在宣告乙個 firstname 的屬性時,編譯器會為我們自動合成乙個 _firstname 的例項變數。

總結: 當我們宣告乙個 readonly 的屬性,外部可能會通過 kvc 修改該屬性值。

為了避免 kvc 修改屬性值,須將定義屬性所在類的類方法 + (bool)accessinstancevariablesdirectly 重寫,使其返回 no.

iOS修改宣告為readonly的值

首先定義乙個測試用的類test test.h import inte ce test nsobject property nonatomic,copy,readonly nsstring testname property nonatomic,assign,readonly nsinteger te...

iOS修改宣告為readonly的屬性值

本文討論的是,對於類中宣告為 readonly 的屬性值,我們就不可以修改其值了麼?如何可以,那麼如何修改呢?為了便於說明,定義乙個aclstudent的類 123 4567 891011 1213 1415 1617 1819 2021 2223 2425 2627 2829 3031 aclst...

定義為指標,宣告為陣列

檔案1中 定義指標 檔案2 宣告為陣列 char str abcd 在檔案1中 extern char str 在檔案2中 在檔案1中str這個變數裡面儲存了乙個字串的首位址假設是0x12345678 這個位址裡面存了a 後面的位址存放了b 依次類推 在檔案2中使用的時候會出現的問題 char c ...