一個毫無道理的iOS問題

Perfect_Dream發表於2019-03-01

昨天晚上在朋友圈看到某猿發了這樣一張圖片:

莫名其妙的問題.png

提問:程式碼1和程式碼2的執行結過是什麼?

剛開始在朋友圈看到這個問題,以為是指標重指向產生野指的問題。但是親自編譯了一下發現並不是。

測試後發現這段程式碼的問題是這樣的:

  1. 程式碼1執行後並不會崩潰,程式碼2執行後會崩潰。
  2. 只有使用initWithUTF8String方法建立NSString會崩潰
  3. 只有字串的內容長度超過10位元組才會奔潰崩潰
  4. 程式碼放到子執行緒或者做延時操作都會崩潰

測試過之後我就在想,為什麼同樣的程式碼因為字串的長度不同就會產生不同的結果呢?

首先我覺得是因為string1被釋放之後,string2被重新建立或是重指向什麼的。 然後就有個下邊兩個圖片:

崩潰記憶體.png

這是崩潰程式碼的記憶體地址

不崩潰記憶體.png

這是不崩潰程式碼的記憶體地址

然後我發現這個問題和重指向並沒有什麼太大關係

然後我就猜想難道是執行時搞的鬼?或者是蘋果的優化機制(PS:當程式碼不滿足或者滿足某個條件就直接跳到結果)? 然而這些猜想都沒有辦法去測試,只能在其他方向找原因了。

然後我又嘗試了將建立的屬性宣告改成統一的,比如weak,copy,strong。 就像這樣:

@property (nonatomic, strong) NSString *string1;
@property (nonatomic, strong) NSString *string2;
複製程式碼

這樣:

@property (nonatomic, weak) NSString *string1;
@property (nonatomic, weak) NSString *string2;
複製程式碼

或者這樣:

@property (nonatomic, copy) NSString *string1;
@property (nonatomic, copy) NSString *string2;
複製程式碼

果然不管怎麼執行都不會崩潰了。

真神奇,然後發現。本來只有一個問題的我,現在變成兩個了,想死。

  1. 為什麼程式碼2會產生奔潰
  2. 為什麼換成其他關鍵字修飾就不會崩潰了

截止到目前為止並沒有發現比較靠譜的解釋,我會持續尋找答案,然後更新到這。

相關文章