对于Objective-C来说最糟糕的13个方面
本文是翻译自 Anton Zherdev——有多年开发经验的独立游戏开发者,他从一个专业开发者的视角深入剖析Objective-C,将其与C、Java等其他语言相比,解读 Objective-C的优与缺,以最为精炼的话语总结出他所认为的Objective-C的13件最为糟糕的事,直指Objective-C的不足之处 (相关iOS开发视频教程《OC语言》)。以下为文章全文:
1、笨重的语法
在Objective-C中,必须要编写大量的代码来声明一个类或属性。对比下面的Objective-C和Scala的代码段,效果不言而喻。
view plaincopy在CODE上查看代码片派生到我的代码片
@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
view plaincopy在CODE上查看代码片派生到我的代码片
class Foo {
private int bar;
public Foo(int bar) {
this.bar = bar;
}
public int getBar() {
return bar;
}
}
view plaincopy在CODE上查看代码片派生到我的代码片
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。
view plaincopy在CODE上查看代码片派生到我的代码片
@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显然要好得多。
view plaincopy在CODE上查看代码片派生到我的代码片
NSArray* array = [foo array];
id item = [array objectAtIndex:0]; //item is anything
view plaincopy在CODE上查看代码片派生到我的代码片
List array = foo.getArray();
A item = array.get(0);
12、不透明的数值包装器
在Objective-C中,要想在集合或其他容器中使用数值是件很费劲的事情,除了原有代码之外,还需添加一个NSNumber类。
view plaincopy在CODE上查看代码片派生到我的代码片
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中,开发者必须要使用到前缀,以避免类名重合。此外,还要在头文件中对所需类进行声明,以防头文件冲突,编译失败。
还有更多编程语言教程集合相关知识登录e良师益友网。