如何防止修改readonly修飾的屬性值

雜貨鋪學徒發表於2019-04-18

當我們的物件的某些個屬性不需要對外提供set方法修改賦值時,那麼我們在定義屬性時會給屬性新增readonly。

1.正常賦值

這樣通過set方法修改readonly修飾的屬性時,會報錯

Assignment to readonly property
複製程式碼

2.存在問題

對於readonly修飾的屬性還是可以通過KVC修改的。

3.如何防止KVC修改readonly修飾的屬性

重寫自定義類的“accessInstanceVariablesDirectly”方法,讓其返回值為NO。 核心程式碼:

+(BOOL)accessInstanceVariablesDirectly{
    return NO;
}

複製程式碼

這樣再通過KVC修改時會報錯

reason: '[<Animal 0x600000019e40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name.'
複製程式碼

4.原理:

當使用setValue:forKey:來設定物件屬性的值時系統會按一下順序來查詢對應的key:

1.查詢是否存在set<key>:這樣格式的方法;

2.如果上面方法未找到,則接受訊息物件的類方法“accessInstanceVariablesDirectly”會返回YES(預設返回YES),再按下面順序繼續查詢;

3._<key> , _is<Key> , <key> , is<Key> 的順序查詢是否存在對應的key,如果找到將改變key所對應的值。

4.最後還是沒有找到對應的存取方法或者例項變數,那麼將走進 setValue:forUndefinedKey: 丟擲如下異常:

reason: '[<Animal 0x60400001ec70> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key namekk.'
複製程式碼

關鍵點便在上面的第2步accessInstanceVariablesDirectly方法的呼叫,系統預設是返回YES,我們將該方法重寫後,讓其返回NO,這樣就直接走進setValue:forUndefinedKey:方法,並丟擲異常,進行提示!

原文引用:修改readonly修飾屬性的值!

相關文章