【问题标题】:Asterisk usage in Objective-CObjective-C 中的星号用法
【发布时间】:2011-01-03 09:46:17
【问题描述】:

我有一个关于在 Objective-C 中使用星号的问题。明确一点:我了解指针是什么以及程序 C 中的所有内容。不过我想知道两件事:

1) 为什么所有(引用)Objective-C 对象都是指针?为什么不是普通变量? (即 NSArray 数组 = [[NSArray alloc] init];)

2) 为什么在调用方法时省略星号?

谢谢!

【问题讨论】:

    标签: c objective-c pointers objective-c-runtime


    【解决方案1】:

    1) 为什么都是(参考) Objective-C 对象指针?为什么不 普通变量? (即 NSArray 数组 = [[NSArray alloc] 初始化];)

    暂时将 Objective-C 对象想象成一个美化的结构。

    NSArray array; 在本地范围内将是堆栈上“分配”的对象。 NSArray *array; 表示由一大块内存支持的对象,通常从堆中分配。

    很久很久以前,Objective-C 决定不支持堆栈上的对象。大多数情况下,因为这样做会使内存管理变得一团糟(主要是,堆栈中的-retain 根本没有任何意义)。

    由于 Objective-C 被设计为 C 的纯超集,并且与 C++ 不同,它不会尝试修改 C 的基本行为,因此在其中包含 * 似乎很自然。

    注意id 打破了这一点,但id 也是一个完全通用的类型。事实上,堆栈中可能有 Objective-C 对象。在 Snow Leopard 中,块实际上是 Objective-C 对象,它们确实从堆栈开始。但是,不支持您在堆栈上创建自己的对象。

    2) 为什么省略星号 调用方法?

    因为您没有取消引用指向对象的指针,并且指向对象的指针在方法实现本身中至关重要。当你说...

    [anArray objectAtIndex: 5];
    

    ...完全等价于写...

    objc_msgSend(anArray, @selector(objectAtIndex:), 5);
    

    ...当你实现上述方法时......

    - (id) objectAtIndex: (NSUInteger) anIndex;
    

    ...完全等价于实现这个C函数...

    id object_at_index(id self, SEL _cmd, NSUInteger anIndex) { ... }
    

    也就是说,Objective-C 方法实际上只是一个接受两个或多个参数的 C 函数。事实上,您可以将这行代码粘贴到任何方法实现中,它会“正常工作”:

    NSLog(@"method %@", NSStringFromSelector(_cmd));
    

    【讨论】:

    • 感谢您的精彩回复,比尔!一切都让完美有意义!快速跟进问题:有没有什么好的资源/书可以推荐来学习这些东西的所有细节方面? (内存存储等)再次感谢!
    • Apple 的教程是一个很好的起点,但我也会选择 Aaron Hilegass 的 Cocoa Programming 的副本。这是他教授的一周课程的教科书。
    【解决方案2】:

    Objective-C 语言将尽可能多的决策从编译时和链接时推迟到运行时。只要有可能,它就会动态地执行操作,例如创建对象和确定要调用的方法。
    所以如果允许的话

    NSArray array = [[NSArray alloc] init];  
    

    在方法中,编译器必须在编译时知道 NSArray 的大小。

    【讨论】:

      猜你喜欢
      • 2011-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      相关资源
      最近更新 更多