關(guān)于UIDatePicker的一個(gè)奇怪問(wèn)題

升級(jí)了Xcode8以后,發(fā)生了很多很奇怪的事情,譬如說(shuō)注釋快捷鍵失效的問(wèn)題,然鵝我們的項(xiàng)目遇到了更加神奇的問(wèn)題,是跟UIDatePicker這個(gè)系統(tǒng)控件相關(guān)。
先上代碼

UIDatePicker *datePicker = [[UIDatePicker alloc] init];
//設(shè)置本地語(yǔ)言
datePicker.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];
//設(shè)置日期顯示的格式
NSDate *curDate = [NSDate date];
[datePicker setDate:curDate animated:NO];
datePicker.datePickerMode = UIDatePickerModeDate;
//設(shè)置accountTextField的inputView控件為datePicker
self.accountTextField.inputView = datePicker;

一段很簡(jiǎn)單很普通的代碼,就莫名奇妙地crash了,堆棧如下

crash堆棧

什么鬼,設(shè)置locale也會(huì)錯(cuò)?那不設(shè)置了行不行捏?也不行!

crash堆棧

從上圖會(huì)看到一個(gè)很奇怪的堆棧,似乎是UIDatePicker在設(shè)置amString的時(shí)候有什么東東有問(wèn)題才導(dǎo)致的crash,而且命令行也有一個(gè)error輸出:
-[__NSCFConstantString name]: unrecognized selector sent to instance 0x109bd8900

google搜索了一通,并沒(méi)有人說(shuō)到這個(gè)問(wèn)題,而且更讓人崩潰的是,自己新建一個(gè)demo工程跑代碼完全沒(méi)問(wèn)題,一用到我們的工程上面就不行了??紤]了一下,說(shuō)不定是build setting有問(wèn)題或者引入了奇怪的第三方庫(kù),嘗試了1個(gè)多小時(shí),放棄了,感覺(jué)這個(gè)方向工作量太大,而且也應(yīng)該不是直接原因。這個(gè)時(shí)候靜下心來(lái),再分析一下crash堆棧,還是看出一點(diǎn)線索了

匯編代碼

留意一下箭頭方向的那一坨匯編,是這樣子的

    0x10ae74dc6 <+346>:  leaq   0x2e7263(%rip), %rdx      ; @"timeZone"
    0x10ae74dcd <+353>:  movq   %rbx, %rsi
    0x10ae74dd0 <+356>:  callq  *0x2c49ca(%rip)           ; (void *)0x000000010e7bfac0: objc_msgSend
    0x10ae74dd6 <+362>:  testq  %rax, %rax
    0x10ae74dd9 <+365>:  je     0x10ae74df1               ; <+389>
    0x10ae74ddb <+367>:  movq   (%r12,%r14), %rdi
    0x10ae74ddf <+371>:  movq   0x2c4782(%rip), %rcx      ; (void *)0x000000010efd71d0: kCFDateFormatterTimeZone
    0x10ae74de6 <+378>:  movq   (%rcx), %rsi
    0x10ae74de9 <+381>:  movq   %rax, %rdx
    0x10ae74dec <+384>:  callq  0x10b0aedc6               ; symbol stub for: CFDateFormatterSetProperty
    0x10ae74df1 <+389>:  movq   (%r12,%r15), %rdi

這段代碼的意思估計(jì)大家也大致看得懂,首先初始化timeZone這個(gè)字符串,然后調(diào)用函數(shù),再設(shè)置屬性,所以就猜測(cè),是不是要先初始化UIDatePickertimeZone才行。

修正后的代碼如下,跑通了。我覺(jué)得這個(gè)問(wèn)題可能我還是沒(méi)找到最終的根源,但是給我?guī)?lái)了另外一個(gè)解決問(wèn)題的思路,就是仔細(xì)考慮一下crash堆棧的匯編相關(guān)代碼,說(shuō)不定就能找到一些特別的解決思路了。

UIDatePicker *datePicker = [[UIDatePicker alloc] init];
//跟隨系統(tǒng)時(shí)區(qū)
datePicker.timeZone = [NSTimeZone systemTimeZone];//一定要先設(shè)置這個(gè),不然會(huì)crash
//設(shè)置本地語(yǔ)言
datePicker.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];
//設(shè)置日期顯示的格式
NSDate *curDate = [NSDate date];
[datePicker setDate:curDate animated:NO];
datePicker.datePickerMode = UIDatePickerModeDate;
//設(shè)置accountTextField的inputView控件為datePicker
self.accountTextField.inputView = datePicker;

奇怪的是,這個(gè)屬性本身系統(tǒng)就已經(jīng)設(shè)置為nil了,這種必須要顯式設(shè)置才能好的邏輯真的不知道是哪里影響了。

timeZone屬性

更為奇怪的是,NSTimeZonesystemTimeZone方法,提示是IOS10以后的方法,WTF?!誰(shuí)能解釋一下這個(gè)瘋狂的IOS?!

systemTimeZone
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容