你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >>  打造Objective

 打造Objective

編輯:IOS開發基礎

man-person-cute-young-large.jpg

作者:夏斌

NSArray NSMutableArray NSDictionary NSMutableDictionary 是我們的在iOS開發中非常常用的類。當然,在享受這些類的便利的同時,它們也給我們帶來一些困擾。粗心我們可能會調用addObject:傳入一個nil, 也有可能是會objectAtIndex:傳入一個越界的index。尤其是在數據基本依賴於服務端返回的的情況,這種crash大幅增加。最近項目上經常出現NSDictionary的setObject:forKey:的nil object的崩潰。我們希望為這種崩潰找一個解決辦法。

解決方案

函數包裝

我們希望能夠用一個統一的方法解決粗心的程序員可能傳入的nil object。我們最先想到的想法是對這些函數進行一個包裝,比如objectAtIndex,我們寫一個如下的函數

- (id)safeObjectAtIndex:(NSUInteger)index
{   
    if (index >= self.count)
    {
        return nil;
    }
    return [self objectAtIndex:index];
}

以後所有調用objectAtIndex的地方統統替換為safeObjectAtIndex。 不過,這顯然不是我想要的,我不希望改變現有的調用方式,大家可能是通過[]或objectAtIndex(不推薦)的方式獲取數組元素,如果要做替換的話改動勢必非常大,而且不便於以後的移植。我們希望代碼調用objectAtIndex的時候,能夠被我們先捕獲到,進行處理之後再調用Cocoa的這個方法。Objective-C作為一門動態語言,有強大的動態加載的能力,提供了Method swizzling實現這樣的功能。現在,黑魔法起飛。

Method swizzling

關於Method swizzling的具體實現,不打算多說,這裡談一下我遇到的問題。最初在做Method swizzling的時候,我嘗試去替換NSArrat的objectAtIndex:,但我始終沒有辦法替換掉這個方法。後來,搞了半天才發現,我們使用的NSAarray或者NSMutableArray並不是我們所看到樣子,它們是class cluster。objectAtIndex:並不是他們的方法,而是他們背後的concrete class: __NSArrayI __NSArrayM的方法。解決了這個問題,剩下的就很簡單了。

使用

直接把XTSafeCollection.hXTSafeCollection.m拖入工程,NSArrayNSMutableArrayNSDictionaryNSMutableDictionary這些類的API以前是怎麼調用的,還怎麼寫,完全不用修改。Demo裡,我全部以傳統的會引起crash的方式調用代碼,以下是我的Demo的代碼和輸出

NSArray *array = @[@"a", @"b"];
NSMutableArray *mutableArray = [@[@"aa", @"bb"] mutableCopy];
    
// Object at index
NSLog(@"%@", array[10]);
NSLog(@"%@", mutableArray[100]);
    
// add object
[mutableArray addObject:nil];
    
// Insert object
[mutableArray insertObject:nil atIndex:0];
[mutableArray insertObject:@"cc" atIndex:10];
    
// Replace object
[mutableArray replaceObjectAtIndex:0 withObject:nil];
[mutableArray replaceObjectAtIndex:10 withObject:@"cc"];
    
// Dictionary
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
mutableDictionary[nil] = @"1";
mutableDictionary[@"1"] = nil;
2015-08-25 18:10:23.932 XTSafeCollection[29067:443479] [__NSArrayI objectAtIndex:] index {10} beyond bounds [0...1]
2015-08-25 18:10:23.933 XTSafeCollection[29067:443479] (null)
2015-08-25 18:10:23.933 XTSafeCollection[29067:443479] [__NSArrayM objectAtIndex:] index {100} beyond bounds [0...1]
2015-08-25 18:10:23.933 XTSafeCollection[29067:443479] (null)
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSArrayM addObject:], NIL object.
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSArrayM insertObject:atIndex:] NIL object.
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSArrayM insertObject:atIndex:] index {10} beyond bounds [0...1].
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSArrayM replaceObjectAtIndex:withObject:] NIL object.
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSArrayM replaceObjectAtIndex:withObject:] index {10} beyond bounds [0...1].
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSDictionaryM setObject:forKey:] NIL key.
2015-08-25 18:10:23.934 XTSafeCollection[29067:443479] [__NSDictionaryM setObject:forKey:] NIL object.

安裝

源碼: https://github.com/wuwen1030/XTSafeCollection

pod XTSafeCollection

已知問題

替換NSMuatbelArray的objectAtIndex:引起鍵盤展示狀態態切換後台的崩潰,拋出*** -[UIKeyboardLayoutStar release]: message sent to deallocated instance 0x7f883beac9c0 在這裡找到了解決方法

last.jpg

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved