ios常見Crash

1.NSInvalidArgumentException 異常

出現(xiàn)這種異常的原因一般是在不可以出現(xiàn)nil數(shù)據(jù)的時候傳入了nil,比如在創(chuàng)建NSDictionary的時候值傳入了nil就會出現(xiàn)這種崩潰錯誤,如果必須傳空需要把nil對象轉(zhuǎn)成NSNull才可以確保不出現(xiàn)這種錯誤,有3種方案可以解決該問題,如下:

方案一:后臺在返回數(shù)據(jù)的時候進行校驗,對空值進行處理。但是在項目中有些空值是有特殊的用途,此種方案不可行。

方案二:在轉(zhuǎn)換成NSDictionary的時候,對后臺返回的數(shù)據(jù)進行校驗,把空值轉(zhuǎn)換成NSNull對象。方案可行,但是需要對現(xiàn)有代碼做大的改動,每次轉(zhuǎn)換的時候都需要進行校驗,太麻煩。業(yè)務(wù)高速發(fā)展時期,這樣做成本太高。

方案三:有沒有一種無須改動現(xiàn)有代碼又能解決該問題呢?答案是有的,可以利用Objective-C的runtime來解決該問題。

NSDictionary插入nil對象會造成崩潰,但是插入NSNull對象是不會造成崩潰的,只要利用runtime的Swizzle Method把nil對象給轉(zhuǎn)換成NSNull對象就可以把該問題給解決了。創(chuàng)建一個NSDictionary的類別,利用runtime的Swizzle Method來替換系統(tǒng)的方法。源碼實現(xiàn)可以參考Glow團隊封裝的NSDictionary+NilSafe(Github上可下載到), 現(xiàn)截取其中的部分代碼如下:

+ (instancetype)gl_dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt {
    id safeObjects[cnt];
    id safeKeys[cnt];
    NSUInteger j = 0;
    for (NSUInteger i = 0; i < cnt; i++) {
        id key = keys[i];
        id obj = objects[i];
        if (!key) {
            continue;
        }
        if (!obj) {
            obj = [NSNull null];
        }
        safeKeys[j] = key;
        safeObjects[j] = obj;
        j++;
    }
    return [self gl_dictionaryWithObjects:safeObjects forKeys:safeKeys count:j];
}

2.data parameter is nil

NSJSONSerialization序列化的時候,傳入data為nil,造成的崩潰,這個問題比較好解決,在序列化的時候,統(tǒng)一加入判斷,判斷data是不是nil即可。

3.unrecognized selector sent to instance 0x15d23910

造成這條崩潰的原因,想必大家都比較熟悉了,就是一個類調(diào)用了一個不存在的方法,造成的崩潰。解決這樣的問題,可以在寫一個方法的時候,判斷一下其類的類型,不符合類型的不讓其調(diào)用

4.SIGSEGV 異常

當去訪問沒有被開辟的內(nèi)存或者已經(jīng)被釋放的內(nèi)存時,就會發(fā)生這樣的異常。另外,在低內(nèi)存的時候,也可能會產(chǎn)生這樣的異常,一般開發(fā)中用到C語言呢的時候比較容易出現(xiàn)這種錯誤,因為ARC并不會對C語言進行內(nèi)存管理,所以用C語言創(chuàng)建的對象一定要手動Free

5.Can't add self as subview crash

造成這個崩潰的原因,一種原因是在push或pop一個視圖的時候,并且設(shè)置了animated:YES,如果此時動畫(animated)還沒有完成,這個時候,你在去push或pop另外一個視圖的時候,就會造成該異常。
解決該異常最簡單的方式是把animated設(shè)置為NO,但是很不友好,把系統(tǒng)自帶的動畫效果給去掉了。另外一種友好的方式就是通過runtime來進行實現(xiàn)了,通過安全的方式,確保當有控制器正在進行入棧或出棧時,沒有其他入棧或出棧操作

6.NSRangeException 異常

越界異常,一般就是數(shù)組越界或者字符串截取越界

7.SIGPIPE 異常

先解釋一下什么是SIGPIPE異常,通俗一點的描述是這樣的:對一個端已經(jīng)關(guān)閉的socket調(diào)用兩次write,第二次write將會產(chǎn)生SIGPIPE信號,該信號默認結(jié)束進程。

那如何解決該問題呢?對SIGPIPE信號可以進行捕獲,也可將其忽略,對于iOS系統(tǒng)來說,只需要把下面這段代碼放在.pch文件中即可。

// 僅在 IOS 系統(tǒng)上支持 SO_NOSIGPIPE
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
    // We do not want SIGPIPE if writing to socket.
    const int value = 1;
    setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(int));
#endif

8.SIGABRT 異常

這是一個讓程序終止的標識,會在斷言、app內(nèi)部、操作系統(tǒng)用終止方法拋出。通常發(fā)生在異步執(zhí)行系統(tǒng)方法的時候。如CoreData、NSUserDefaults等,還有一些其他的系統(tǒng)多線程操作。
注意:這并不一定意味著是系統(tǒng)代碼存在bug,代碼僅僅是成了無效狀態(tài),或者異常狀態(tài)。

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

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

  • 背景 眾所周知,對于移動客戶端而言,crash對于用戶是一種非常糟糕的體驗,crash率對于一款移動應(yīng)用而言也是一...
    東野浪子閱讀 7,589評論 2 8
  • 一、訪問了一個已經(jīng)被釋放的對象 在不使用 ARC 的時候,內(nèi)存要自己管理,這時重復(fù)或過早釋放都有可能導(dǎo)致 Cras...
    李華光閱讀 1,912評論 0 1
  • 在日常項目中,常見的crash包括:給NSNull發(fā)送消息,數(shù)組越界,字典傳空值等。我們可以對這些crash簡單的...
    oncezou閱讀 1,641評論 0 1
  • 一、經(jīng)常遇到的bug 1:訪問了一個已經(jīng)被釋放的對象(MRC環(huán)境中常見) obj這個對象已經(jīng)被釋放,但是指針沒有置...
    lbfly_boy閱讀 1,284評論 0 1
  • 代碼下載 iOS Crash 殺手排名 殺手 NO.1 NSInvalidArgumentException 異常...
    雷鳴1010閱讀 2,607評論 1 3

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