1. 程式人生 > >你遇到過setNilValueForKey崩潰嗎

你遇到過setNilValueForKey崩潰嗎

今天更新了某個app之後發現了閃退,突然有個想法想要看看崩潰的原因。

查看了手機上的崩潰日誌如下:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Application Specific Information:
abort() called

Filtered syslog:
None found

Last Exception Backtrace:
0   CoreFoundation                  0x18b386fe0 __exceptionPreprocess + 124
1   libobjc.A.dylib                 0x189de8538 objc_exception_throw + 55
2   CoreFoundation                  0x18b386f28 +[NSException raise:format:] + 115
3   Foundation                      0x18be3669c -[NSObject+ 808604 (NSKeyValueCoding) setNilValueForKey:] + 87
4   Foundation                      0x18bd9c68c -[NSObject+ 177804 (NSKeyValueCoding) setValue:forKey:] + 271
5   nplus                           0x1001a4344 0x10008c000 + 1147716
6   nplus                           0x1001a34c0 0x10008c000 + 1144000

發現了一個關鍵資訊[NSObject+ 808604 (NSKeyValueCoding) setNilValueForKey:]

然後看了一下這個方法的api:

Instance Method
setNilValueForKey:

Invoked by setValue:forKey: when it’s given a nil value for a scalar value (such as an int or float).

根據這個意思,如果通過kvc賦值的時候,給一個基本資料型別比如int float設定一個nil值,就會呼叫這個方法。

Subclasses can override this method to handle the request in some other way, such as by substituting 0 or a sentinel value for nil and invoking setValue:forKey: again or setting the variable directly. The default implementation raises an NSInvalidArgumentException.

這個方法預設會觸發異常。除非子類重寫這個方法,做一些需要的邏輯。

上面的這些只是個推測,需要驗證。

驗證過程很簡單。隨便寫個專案,新增一個int型例項變數,並設定其值為nil。發現確實會崩潰。然後對比下崩潰日誌,發現一模一樣。所以上面推測是對的。