1. 程式人生 > >iOS 陣列越界,防Crash處理,效能優化 —— HERO部落格

iOS 陣列越界,防Crash處理,效能優化 —— HERO部落格

常常會看到這樣的崩潰日誌-[__NSArrayM objectAtIndex:]: index4 beyond bounds [0 ..1],陣列越界。

舉個列子:

    int index = 3;
    NSArray *array = @[@"z", @"x", @"c"];
    [array objectAtIndex:index];

這段程式碼執行會崩潰,陣列越界,解決辦法有很多,比如我們可以嘗試增加一個條件判斷:

    int index = 3;
    NSArray *array = @[@"z", @"x", @"c"];
    if (index < array.count) {
        [array objectAtIndex:index];
    }

或者使用try...catch捕獲異常

    int index = 3;
    NSArray *array = @[@"z", @"x", @"c"];
    @try {
        //可能丟擲異常的程式碼
        [array objectAtIndex:index];
    }
    @catch (NSException *exception) {
        //處理異常
        NSLog(@"exception: %@", exception.reason);
    }
    @finally {
        //finally程式碼塊是可選的,如果寫了,不管有沒有異常,block內的程式碼都會被執行
        NSLog(@"finally");
    }

上面方法已經可以避免crash,為了避免冗餘的程式碼,寫一個NSArray的分類,利用runtime替換NSArray的物件方法objectAtIndex:,在這裡進行判斷,捕獲異常:

#import <Foundation/Foundation.h>

@interface NSArray (Crash)

@end

/*** ---------------分割線--------------- ***/ 

#import "NSArray+Crash.h"
#import <objc/runtime.h>

@implementation NSArray (Crash)

+ (void)load
{
    [super load];
    
    //替換不可變陣列方法
    Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
    Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtSafeIndex:));
    method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
    
    //替換可變陣列方法
    Method oldMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
    Method newMutableObjectAtIndex =  class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(mutableObjectAtSafeIndex:));
    method_exchangeImplementations(oldMutableObjectAtIndex, newMutableObjectAtIndex);
}

- (id)objectAtSafeIndex:(NSUInteger)index
{
    if (index > self.count - 1 || !self.count) {
        @try {
            return [self objectAtSafeIndex:index];
        }
        @catch (NSException *exception) {
            NSLog(@"exception: %@", exception.reason);
            return nil;
        }
        
    }else {
        return [self objectAtSafeIndex:index];
    }
}

- (id)mutableObjectAtSafeIndex:(NSUInteger)index
{
    if (index > self.count - 1 || !self.count) {
        @try {
            return [self mutableObjectAtSafeIndex:index];
        }
        @catch (NSException *exception) {
            NSLog(@"exception: %@", exception.reason);
            return nil;
        }
        
    }else {
        return [self mutableObjectAtSafeIndex:index];
    }
}

@end


相關推薦

iOS 陣列越界Crash處理效能優化 —— HERO部落

常常會看到這樣的崩潰日誌-[__NSArrayM objectAtIndex:]: index4 beyond bounds [0 ..1],陣列越界。 舉個列子: int index = 3; NSArray *array = @[@"z", @"x"

iOS 多工全部執行完後再執行操作 —— HERO部落

介紹一下開發中遇到多個任務的情況及處理方法。1. 有兩個載入圖片的任務,全部載入完成後在進行相應操作,耗時操作不應該放在主執行緒,所以開啟子執行緒載入,通過佇列組實現:{ // 建立佇列組 dispatch_group_t group = dispatch_

Google Breakpad 之一跨平臺crash 處理上報系統簡介

C/C++程式最棘手的時候就是一個字“掛”,總是經常和不經常的掛掉,尤其是那些線上的不經常掛的情況,光看日誌定位問題真的很難。 為解決C掛掛的問題,有必要提供一個跨平臺的crash處理系統,目前已知的支援平臺有windows 、Linux、 OS X 、android、等待

安卓開發 RecycleView 中notifyItemRemoved遇到的那些坑 IndexOutOfIndexException、刪除錯亂陣列越界等終極解決方案多人親測可行

當我們在開發過程中要刪除RecycleView中的某個item時,都喜歡notifyItemRemoved方法帶來的動畫效果,然而,會遇到錯亂的坑,主要有三個,如下: 再刪除後面的item,會發生錯

Python自動化開發課堂筆記【Day03】 - Python基礎(字符編碼使用文件處理函數)

賦值 創建 解釋器 使用 重復 closed 操作 邏輯 默認 字符編碼使用 1. 文本編輯器如何存取文件 文本編輯器相當一個運行在內存中的進程,所以文件內容在編輯未存儲時都是在內存中的,尚未存儲在硬盤之中,在沒有保存之前,所編輯的任何文本都只是一堆字符,沒有任何邏輯上的意

JSOUP教程JSOUP 亂碼處理JSOUP生僻字亂碼解決方案

catch 緩存 dem 頭信息 win64 -- 默認 set 開啟 JSOUP亂碼情況產生 這幾天我用 JSOUP 多線程的方式,爬取了200 多萬數據,數據為各地的地名相關。結果有小部分數據,不到 1 萬亂碼。我先檢查了我的編碼為UTF-8 ,覺得應該沒有問題。代碼基

智能追錄器——基於人臉識別圖像處理機器人視覺交叉領域

拍照 運行 隨著 閾值 功能 此外 領域 人的 自由度 智能追錄器 背景設想:基於自拍桿的靈感,是否需要這樣的一個機器人,幫你錄像,或者拍照 。 (一)視覺模塊 機器人頂端安裝手機支架,其下連接多自由度的舵機雲臺,用於追蹤單平面內的人臉偏移。 (二)運動模塊 機器人底

iOS-APP-執行時Crash工具XXShield練就

原文地址 前言 正在執行的 APP 突然 Crash,是一件令人不爽的事,會流失使用者,影響公司發展,所以 APP 執行時擁有防 Crash 功能能有效降低 Crash 率,提升 APP 穩定性。但是有時候 APP Crash 是應有的表現,我們不讓 APPCrash 可能會導致別的邏輯錯誤

深度學習視訊吳恩達CS231n斯坦福計算機視覺牛津大學xDeepMind 自然語言處理莫煩Tensorflow

1. 吳恩達 最新深度學習視訊  網易雲課堂 http://mooc.study.163.com/smartSpec/detail/1001319001.htm 《深度學習筆記v5.32》 pdf下載 連結:https://pan.baidu.com/s/1m8c7OdCJJZ2

人工智慧深度學習計算機視覺自然語言處理機器學習百度網盤視訊教程

人工智慧,深度學習,計算機視覺,自然語言處理,機器學習視訊教程下載: 1. CS224D 2. NLP到Word2vec 3. Opencv3影象處理 4. Tensorflow 5. 機器學習 6. 人工智慧課程 7. 聊天機器人視訊教程 8. 自然語言處理 獲取檔案下載連結

將資料庫查詢資料封裝到XML檔案中進行格式化處理並進行加密操作和解密操作

1.pom檔案 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7&l

Python 資料庫操作mysqlsql注入引數化

  demo.py(防sql注入): from pymysql import * def main(): find_name = input("請輸入物品名稱:") # 建立Connection連線 conn = connect(host='local

滑鼠操作事件,擷取攝像頭視訊中區域圖片預處理識別數字

通過回撥函式擷取攝像頭視訊感興趣區域(儀器數字區域),並進行預處理,然後識別,程式碼如下 效果圖如下 //滑鼠操作事件,擷取攝像頭視訊中區域,識別圖片 #include <opencv2/core/core.hpp>   #include <openc

go語言基礎語法:異常處理文字檔案處理JSON處理檔案操作

一、異常處理 1.err介面的使用 err1 := fmt.Errorf("%s", "this is normal error") fmt.Println("err1=", err1) err2 := errors.New("this is normal error,

js 對固定的計算做快取處理比如計算乘積;

對固定的計算,做快取處理,比如計算乘積;   var mult = (function() { var cache = {}; var calculate = function() { var a = 1; for(var i = 0, l = arguments.

資料預處理備忘(特徵選擇三大降維技術資料形態處理模型評估)

這一塊的每一個小點都可以引申出很多的東西,所以先做一個大概,用以備忘,持續更新。 *一般過程: (1)資料採集 資料採集是最基本也很耗時間的工作。比如對於具體的工程事件,需要考慮採集哪些型別的資料?需要哪些屬性?需要多少資料支撐?然後再實際去採集這些資料,離線採集?線上獲取? (2)

Fresco 的封裝快速上手影象後處理超大圖高清預覽縮小放大雙擊放大等一一俱全

因為某些原因,現在使用 jitpack.io,還請使用依賴的各位切換到 jitpack。在 project 下的 build.gradle 新增allprojects { repositories { ... maven { url 'https://jitpack.i

量化:從okex獲取k線資料symbol(交易對) 去重處理存入到mongodb資料庫

import json import time import pymongo from threading import Thread import pandas as pd from urllib.request import Request, urlopen

iOS AFN監聽網路封裝網路請求 —— HERO部落

對AFN網路請求進行封裝,程式碼如下:/************************* .h檔案 *************************/ #import <Foundation/Foundation.h> @interface HWManage

期貨現貨資料處理平穩性檢驗協整檢驗granger因果檢驗

library(lmtest)library(tseries)library(urca)da1<-read.table("egg_futures.txt",header = T)da2<-read.table("egg_marketprice.txt",heade