注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

(转载)独立开发者的自白:Objective-C最糟糕的13件事  

2016-04-06 11:54:47|  分类: IOS |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

(转载)独立开发者的自白:Objective-C最糟糕的13件事

http://www.csdn.net/article/2013-12-17/2817832-top-13-worst-things-about-objective-c

摘要:本文的作者是一名具有多年开发经验的独立游戏开发者,他从一个专业开发者视角深入剖析Objective-C,将其与其他编程语言相比,解读Objective-C的优与缺,并总结出Objective-C13件最为糟糕的事。

本文的作者Anton Zherdev是一名具有多年开发经验的独立游戏开发者,他从一个专业开发者的视角深入剖析Objective-C,将其与CJava等其他语言相比,解读Objective-C的优与缺,以最为精炼的话语总结出他所认为的Objective-C13件最为糟糕的事,直指Objective-C的不足之处,与列位开发者分享。以下为文章全文:

 

1. 笨重的语法

 

Objective-C中,必须要编写大量的代码来声明一个类或属性。对比下面的Objective-CScala的代码段,效果不言而喻。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

@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 

[js] view plaincopyCODE上查看代码片派生到我的代码片

class Foo { 

   private int bar; 

   public Foo(int bar) { 

        this.bar = bar; 

   } 

   public int getBar() { 

        return bar; 

   } 

[js] view plaincopyCODE上查看代码片派生到我的代码片

class Foo(bar : Int) 

2. 方括号

 

前缀括号是一件非常虐心的事情,尽管Objective-CIDE自动解决这一问题,却也大大降低了代码的可读性。

 

3. 内存管理

 

与具有垃圾回收器的编程语言相比,Objective-C的内存更容易泄漏。虽然垃圾回收器可能会导致程序不定时回收,但也可通过设置来避免。在Objective-C中,尽管已经有ARC来解决这一问题,并且,开发者可以很好地利用它来解决一些弱引用的问题,却还存在着无法解析引用周期的状况。

 

举个例子,如果你在block中使用self,并将其发送给另一个存储该block的类,便会导致内存泄漏,而且还很难发现。并且,如果想要在类字段中保存block,就必须要将其copy过来,否则,当block被调用时,程序也就崩溃了。

 

4. 动态且不安全的类型系统

 

Objective-C有一个非常奇怪的类型系统。任何消息,只要在视图中可声明,就可以将其发送给id类对象,但却无法回避id

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

@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显然要好得多。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

NSArray* array = [foo array]; 

id item = [array objectAtIndex:0]; //item is anything 

[js] view plaincopyCODE上查看代码片派生到我的代码片

List<A> array = foo.getArray(); 

A item = array.get(0); 

6. 核心库集匮乏

 

Objective-C的核心库中,缺少诸如分类设置、字典(地图)、链表、队列等实用集。没有它们,在进行红黑树分类和字典等开发管理时会花费大量的时间。

 

还有一个问题就是缺乏几项非常不错的功能,尤其是函数式编程能力有所缺失,尽管如此,但在Objective中,也有非常不错的一项功能,就是开发者可以使用分类简单地扩展核心集。

 

7. 缺少枚举

 

尽管Objective-C包含有C的枚举,但却仅仅只是一组变量,开发者必须要编写代码来实现一些类似于Java的枚举,比如链接属性等。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

enum Foo { 

    Foo1(1), 

    Foo2(2), 

    Foo2(3); 

    final int bar; 

    Foo(int bar) { 

        this.bar = bar; 

    } 

8. 可怕的block语法

 

blockObjective-C一项非常强大的功能,但我却不知如何声明带有block类型的变量或函数参数。看下面这段代码便可知晓。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

//Declare variable foo 

void (^foo)(id obj, NSUInteger idx, BOOL *stop); 

9. 操作符重载缺失

 

如果说无需操作符重载的话,难免有些欠妥,因为定义向量数学运算符是件很正常的事情,它使代码更具有可读性。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

[[[a add:b] sub:[c mul:f]] div:f]; 

(a + b - c*f)/f; 

10. 匿名类不足

 

定义一个协议或接口并不像想象中那么简单,要想轻而易举地实现,就必须要先实现一个完整的类。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

@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 

[js] view plaincopyCODE上查看代码片派生到我的代码片

interface I { 

   void f(); 

  

class Foo { 

   void foo() { 

       I i = new I() { 

         void f() { 

             bar(); 

         } 

     }; 

  } 

  void bar() { 

  } 

11. 糟糕的构造函数

 

使用构造函数创建新对象很常见,但在Objective-C中,要想创建对象,还需调用两个函数。当然,开发者可以编写方法直接避免该问题的发生。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

@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类。

 

[js] view plaincopyCODE上查看代码片派生到我的代码片

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中,开发者必须要使用到前缀,以避免类名重合。此外,还要在头文件中对所需类进行声明,以防头文件冲突,编译失败。

  评论这张
 
阅读(143)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017