更好的閱讀體驗請點擊 原文git
接上篇,其實在接觸Ruby不久後,我就萌生了改造ObjC的Cocoa框架的想法。爲何要改造?只爲可以提升開發OC項目的效率。同時我也完成了一些改造工做,詳見像Ruby同樣寫ObjC,用block實現鏈式方法調用程序員
說到改造這個問題,我想起曾經有人說,合格的程序員都會不斷追求自動化,不斷追求代碼的解耦與複用,不斷追求拓展技術的邊界。咱們也每每會從這三個方向找切入口,例如OC和Python同樣充斥了一些C語言函數形式的方法或者宏,例如NSLog()
、NSLocalizedString()
,或是CoreGraphic框架中一系列的C函數,更有甚者GCD(Grand Central Dispatch)徹底是C函數代碼,但GCD由於把多線程編程作的跟if/else同樣好用,因此用多了也都接受了。github
<!--more-->算法
咱們今天就從NSLocalizedString這個宏做爲切入口,舉一個例子:編程
//慣用方法 NSString* str = NSLocalizedString(@"你好,世界",nil);
從OOP的角度思考,咱們不難想到字符串的本地化轉換,徹底能夠做爲NSString類的實例方法來設計,而不是像NSLocalizedString宏這樣的設計,這個設計能夠說堪比Python的len()方法。多線程
從新設計的本地化接口框架
NSString* str = [@"你好,世界" localizedString];
這樣調用不只更符合咱們的思惟邏輯,也更符合OOP的理念,而且和NSString其餘的接口也保持了一致性。使用ObjC的Category特性,就能夠輕鬆實現函數
@interface NSString (add) - (NSString*)localizedString; @end @implementation NSString(add) - (NSString*)localizedString;{ return NSLocalizedString(self, nil); } @end
一樣的咱們還能夠給NSString或者其餘類型增長各類各樣的類別(Category)進行拓展,例如比較有名集大成框架YYKit,在NSString擴展中加入各類摘要算法轉換方法,給實際開發帶來了極大的便利。優化
若是第一個栗子不能跟你產生多少共鳴,那就請看接下來的栗子:給NSArray增長高階函數Map,相似的Filter,Reduce函數在Python、JavaScript、Swift、Ruby中都是標配了,而OC則顯得略有落後,但落後並不妨礙咱們進行改造,一樣給NSArray增長Category方法,實現依賴於OC對block的支持spa
@interface NSArray (Functional) - (NSArray*)map:(id (^)(id x))map; @end @implementation NSArray (Functional) - (NSArray*)map:(id (^)(id))map { NSMutableArray* array = [NSMutableArray array]; [self enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { id x = map(obj); if(x) [array addObject:x]; }]; return [array copy]; } @end
block的出現至關於提升了代碼塊的身份,雖然它還不是OC的一等公民,但已經能夠和實例對象分庭抗禮,做爲參數進行傳遞了。若是你是一個不太明白block機制的新手,我這裏還有一篇教程推薦給你。若是瞭解block,上面的代碼就很好理解了,沒有任何優化,僅僅是封裝了拿東西
和包裝
這兩個步驟。
那,NSArray實現Map方法意味着什麼呢?意味着咱們加工一組數據時,只要專心數據的加工工做就好。
NSArray* a = @[@"a",@"b",@"c"]; a = [a map:^id(id x) { return [x uppercaseString]; }]; NSLog(@"%@",a);
(
A,
B,
C
)
這個問題其實不用討論也知道能夠,由於咱們都有過複製粘貼重複寫代碼的經歷,而這種代碼封裝和複用,甚至比複製粘貼更簡單,每使用一次,都能節省幾秒鐘甚至幾分鐘的時間,一併節省很多精力,終年累月則是受益無窮。