獨立開發者的自白:Objective-C最糟糕的13件事
本文的作者Anton Zherdev是一名具有多年開發經驗的獨立遊戲開發者,他從一個專業開發者的視角深入剖析Objective-C,將其與C、Java等其他語言相比,解讀Objective-C的優與缺,以最為精煉的話語總結出他所認為的Objective-C的13件最為糟糕的事,直指Objective-C的不足之處,與列位開發者分享。以下為文章全文:
1. 笨重的語法
在Objective-C中,必須要編寫大量的程式碼來宣告一個類或屬性。對比下面的Objective-C和Scala的程式碼段,效果不言而喻。
@interface Foo : NSObject @property (readonly) int bar; - (instancetype)initWithBar:(int)bar; + (instancetype)fooWithBar:(int)bar; @end @implementation Foo - (instancetype)initWithBar:(int)bar { self = [super init]; if (self) { _bar = bar; } return self; } + (instancetype)fooWithBar:(int)bar { return [[self alloc] initWithBar:bar]; } @end
class Foo { private int bar; public Foo(int bar) { this.bar = bar; } public int getBar() { return bar; } }
class Foo(bar : Int)
2. 方括號
字首括號是一件非常虐心的事情,儘管Objective-C有IDE自動解決這一問題,卻也大大降低了程式碼的可讀性。
3. 記憶體管理
與具有垃圾回收器的程式語言相比,Objective-C的記憶體更容易洩漏。雖然垃圾回收器可能會導致程式不定時回收,但也可通過設定來避免。在Objective-C中,儘管已經有ARC來解決這一問題,並且,開發者可以很好地利用它來解決一些弱引用的問題,卻還存在著無法解析引用週期的狀況。
舉個例子,如果你在block中使用self,並將其傳送給另一個儲存該block的類,便會導致記憶體洩漏,而且還很難發現。並且,如果想要在類欄位中儲存block,就必須要將其copy過來,否則,當block被呼叫時,程式也就崩潰了。
4. 動態且不安全的型別系統
Objective-C有一個非常奇怪的型別系統。任何訊息,只要在檢視中可宣告,就可以將其傳送給id類物件,但卻無法迴避id。
@interface Foo : NSObject - (void)foo; @end @implementation Foo - (void)foo{} @end @interface Bar : NSObject - (void)bar; @end @implementation Bar - (void)bar { [(id)self foo]; //OK [(id)self bar]; //OK, but runtime error [(id)self qux]; //Compiler error Foo* foo = self; //OK } @end
5. 不支援泛型
在Objective-C中,要想檢視容器類所屬是不可能的,而且,編譯器也不能進行檢查。這方面,Java顯然要好得多。
NSArray* array = [foo array]; id item = [array objectAtIndex:0]; //item is anything
List<A> array = foo.getArray(); A item = array.get(0);
6. 核心庫集匱乏
在Objective-C的核心庫中,缺少諸如分類設定、字典(地圖)、連結串列、佇列等實用集。沒有它們,在進行紅黑樹分類和字典等開發管理時會花費大量的時間。
還有一個問題就是缺乏幾項非常不錯的功能,尤其是函數語言程式設計能力有所缺失,儘管如此,但在Objective中,也有非常不錯的一項功能,就是開發者可以使用分類簡單地擴充套件核心集。
7. 缺少列舉
儘管Objective-C包含有C的列舉,但卻僅僅只是一組變數,開發者必須要編寫程式碼來實現一些類似於Java的列舉,比如連結屬性等。
enum Foo { Foo1(1), Foo2(2), Foo2(3); final int bar; Foo(int bar) { this.bar = bar; } }
8. 可怕的block語法
block是Objective-C一項非常強大的功能,但我卻不知如何宣告帶有block型別的變數或函式引數。看下面這段程式碼便可知曉。
//Declare variable foo void (^foo)(id obj, NSUInteger idx, BOOL *stop);
9. 操作符過載缺失
如果說無需操作符過載的話,難免有些欠妥,因為定義向量數學運算子是件很正常的事情,它使程式碼更具有可讀性。
[[[a add:b] sub:[c mul:f]] div:f]; (a + b - c*f)/f;
10. 匿名類不足
定義一個協議或介面並不像想象中那麼簡單,要想輕而易舉地實現,就必須要先實現一個完整的類。
@protocol I - (void)f; @end @interface Foo : NSObject - (void)foo; - (void)qux; @end @implementation Foo - (void)foo { id<I> i = [[Baz alloc] initWithFoo:self]; } @end @interface Baz : NSObject<I> - (instancetype)initWithFoo:(Foo*)foo; @end @implementation B { Foo* _foo; } - (instancetype)initWithFoo:(Foo*)foo { self = [super init]; if(self) { _foo = foo; } return self; } - (void)f { [_foo bar]; } @end
interface I { void f(); } class Foo { void foo() { I i = new I() { void f() { bar(); } }; } void bar() { } }
11. 糟糕的建構函式
使用建構函式建立新物件很常見,但在Objective-C中,要想建立物件,還需呼叫兩個函式。當然,開發者可以編寫方法直接避免該問題的發生。
@interface Foo : NSObject - (instancetype)initWithBar:(int)bar; + (instancetype)newWithBar:(int)bar; @end @implementation Foo { int* _bar; } - (instancetype)initWithBar:(int)bar { self = [super init]; if(self) { _bar = bar; } return self; } + (instancetype)newWithBar:(int)bar { return [[self alloc] initWithI:bar]; } @end
12. 不透明的數值包裝器
在Objective-C中,要想在集合或其他容器中使用數值是件很費勁的事情,除了原有程式碼之外,還需新增一個NSNumber類。
int a = 1; int b = 2; int c = a + b; NSNumber* aWrap = @(a); NSNumber* bWrap = @(b); NSNumber* cWrap = @([aWrap intValue] + [bWrap intValue]);
13. 缺乏包管理系統
在Objective-C中,開發者必須要使用到字首,以避免類名重合。此外,還要在標頭檔案中對所需類進行宣告,以防標頭檔案衝突,編譯失敗。
相關文章
- 一個獨立開發者的失敗自白
- 創業教訓:一個獨立開發者的失敗自白創業
- 獨立開發者入行之前應該知道的8件事
- 獨立開發者的程式碼簽名
- 拒絕Epic Games Store獨佔協議的獨立開發者GAM協議
- Solo 開發者週刊 (第13期):獨立開發者的創新集——橘貓、記一杯與Newcar
- 獨立開發者:走向全能的五大技能
- 全球獨立開發者鼓舞人心的開發故事
- 一個獨立開發者的逆襲成長之路
- 優秀的開發者 vs. 糟糕的開發者
- Price Tag | INTERVIEW 04 | 獨立開發者 LarryView
- 從業遊戲 22 年給獨立開發者的建議遊戲
- 獨立開發者的市場營銷:市場調查
- 分享做為獨立開發者的一些經驗
- 獨立任務最優排程
- 每一個C#開發者必須知道的13件事情C#
- 一個骨灰級塞班開發者的自白
- 什麼促使你走上獨立開發者之路?
- 【教你賺錢】獨立開發者荒野求生之道
- 乾貨 | 作為前端開發者如何邁向獨立開發者前端
- 90% 以上的獨立開發者,敗在了認知環節
- 獨立開發者分享:遊戲本地化的6個建議遊戲
- 一位跨平臺開發者的自白
- 一位骨灰級塞班開發者的自白
- 製作“成長”系列的獨立開發者,會如何面對死亡?
- 作為獨立開發者 別人不會告訴你的事
- Javier Cabrera:闡述如何治療獨立開發者的孤獨綜合症
- 獨立站運營——獨立站的3種搭建方式
- 思否獨立開發者丨@浩:選擇獨立開發的我,和大齡女青年不結婚的理由一樣
- 獨立開發者談品牌的續作化和再創造的問題
- Rami Ismail談3A遊戲和獨立開發者的互相借鑑方式AI遊戲
- 【技巧篇】5 分鐘教你成為會賺錢的獨立開發者
- 獨立開發者創業過程中會犯的14個錯誤創業
- 從獨立開發者視角看F2P遊戲的發行遊戲
- 我為什麼選擇成為獨立開發者
- 0219 - 怎麼才能成為獨立開發者?
- 經典老遊戲,在獨立開發者手中復甦遊戲
- 開發者觀點:「獨立」一詞已失去其意義