當我們的物件的某些個屬性不需要對外提供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修飾屬性的值!