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

原创
小哥 2年前 (2023-05-24) 阅读数 37 #大杂烩

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

本文作者Anton Zherdev他是一位拥有多年开发经验的独立游戏开发者,从专业开发者的角度深入分析。Objective-C,将其与C、Java与其他语言相比,口译Objective-C根据Objective-C的13最糟糕的事情是指出Objective-C与所有开发人员分享缺点。以下为文章全文:

1. 笨拙的语法

在Objective-C在中,需要编写大量代码来声明类或属性。比较以下内容Objective-C和Scala代码片段的效果是不言而喻的。

[js] view plain copy

  1. @ interface Foo : NSObject
  2. @property (readonly) int bar;
  3. - (instancetype)initWithBar:( int )bar;
  4. + (instancetype)fooWithBar:( int )bar;
  5. @end
  6. @implementation Foo
  7. - (instancetype)initWithBar:( int )bar {
  8. self = [ super init];
  9. if (self) {
  10. _bar = bar;
  11. }
  12. return self;
  13. }
  14. + (instancetype)fooWithBar:( int )bar {
  15. return [[self alloc] initWithBar:bar];
  16. }
  17. @end

[js] view plain copy

  1. class Foo {
  2. private int bar;
  3. public Foo( int bar) {
  4. this .bar = bar;
  5. }
  6. public int getBar() {
  7. return bar;
  8. }
  9. }

[js] view plain copy

  1. 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。

[js] view plain copy

  1. @ interface Foo : NSObject

  2. - ( void )foo;

  3. @end

  4. @implementation Foo

  5. - ( void )foo{}

  6. @end

  7. @ interface Bar : NSObject

  8. - ( void )bar;

  9. @end

  10. @implementation Bar

  11. - ( void )bar {

  12. [(id)self foo]; //OK

  13. [(id)self bar]; //OK, but runtime error

  14. [(id)self qux]; //Compiler error

  15. Foo* foo = self; //OK

  16. }

  17. @end

5. 不支持泛型

在Objective-C无法查看容器类的所有权,并且编译器无法执行检查。在这方面,Java显然要好得多。

[js] view plain copy

  1. NSArray* array = [foo array];
  2. id item = [array objectAtIndex:0]; //item is anything

[js] view plain copy

  1. List array = foo.getArray();
  2. A item = array.get(0);

6. 缺少核心库集

在Objective-C在核心库中,缺乏分类设置、字典(maps)、链表、队列等实用集。没有他们,正在进行中 红黑树 类别和词典的开发和管理可能需要大量时间。

另一个问题是缺少几个非常好的功能,特别是缺乏函数式编程能力。Objective还有一个非常好的功能,那就是开发人员可以使用分类轻松扩展核心集。

7. 缺少枚举

尽管Objective-C包含有C枚举,但它只是一组变量,开发人员必须编写代码来实现类似于Java的枚举,例如链接属性。

[js] view plain copy

  1. enum Foo {
  2. Foo1(1),
  3. Foo2(2),
  4. Foo2(3);
  5. final int bar;
  6. Foo( int bar) {
  7. this .bar = bar;
  8. }
  9. }

8. 可怕的block语法

block是Objective-C一个非常强大的功能,但我不知道如何声明它block类型的变量或函数参数。您可以通过查看下面的代码来查看。

[js] view plain copy

  1. //Declare variable foo
  2. void (^foo)(id obj, NSUInteger idx, BOOL *stop);

9. 缺少运算符重载

如果不需要算子重载,那不可避免地有些不合适,因为定义向量数学算子是很正常的事情,使代码更具可读性。

[js] view plain copy

  1. [[[a add:b] sub:[c mul:f]] div:f];
  2. (a + b - c*f)/f;

10. 匿名类不足

定义协议或接口并不像想象的那么简单。若要轻松实现它,必须首先实现一个完整的类。

[js] view plain copy

  1. @protocol I

  2. - ( void )f;

  3. @end

  4. @ interface Foo : NSObject

  5. - ( void )foo;

  6. - ( void )qux;

  7. @end

  8. @implementation Foo

  9. - ( void )foo {

  10. id i = [[Baz alloc] initWithFoo:self];

  11. }

  12. @end

  13. @ interface Baz : NSObject

  14. - (instancetype)initWithFoo:(Foo*)foo;

  15. @end

  16. @implementation B {

  17. Foo* _foo;

  18. }

  19. - (instancetype)initWithFoo:(Foo*)foo {

  20. self = [ super init];

  21. if (self) {

  22. _foo = foo;

  23. }

  24. return self;

  25. }

  26. - ( void )f {

  27. [_foo bar];

  28. }

  29. @end

[js] view plain copy

  1. interface I {

  2. void f();

  3. }

  4. class Foo {

  5. void foo() {

  6. I i = new I() {

  7. void f() {

  8. bar();

  9. }

  10. };

  11. }

  12. void bar() {

  13. }

  14. }

11. 错误的构造函数

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

[js] view plain copy

  1. @ interface Foo : NSObject
  2. - (instancetype)initWithBar:( int )bar;
  3. + (instancetype)newWithBar:( int )bar;
  4. @end
  5. @implementation Foo {
  6. int * _bar;
  7. }
  8. - (instancetype)initWithBar:( int )bar {
  9. self = [ super init];
  10. if (self) {
  11. _bar = bar;
  12. }
  13. return self;
  14. }
  15. + (instancetype)newWithBar:( int )bar {
  16. return [[self alloc] initWithI:bar];
  17. }
  18. @end

12. 不透明的数字包装器

在Objective-C除了原始代码外,还需要添加一个 NSNumber类

[js] view plain copy

  1. int a = 1;
  2. int b = 2;
  3. int c = a + b;
  4. NSNumber* aWrap = @(a);
  5. NSNumber* bWrap = @(b);
  6. NSNumber* cWrap = @([aWrap intValue] + [bWrap intValue]);

13. 缺乏包裹管理系统

在Objective-C在中,开发人员必须使用前缀来避免类名重叠。此外,有必要在头文件中声明所需的类,以防止头文件冲突和编译失败。

(编译/唐小引 责编/张宁)

文章来源: Anton Zherdev个人博客

本文为CSDN汇编整理,未经许可不得转载。如需转载,请联系market#csdn.net(#换成@)

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门