【问题标题】:Why is everything a pointer in Objective-C为什么Objective-C中的一切都是指针
【发布时间】:2011-12-02 21:34:57
【问题描述】:

我来自 PHP/Javascript 背景,在大多数情况下,事物直接存储在变量中,我们也有对象/类/方法等。这是 OOP。

现在我开始学习 Objective-C。我了解指针的基础知识。但现在一切都是指针。这是我没有得到的部分。为什么我们不像 PHP/Javascript 那样直接赋值?毕竟我们还在做 OOP。

谢谢

【问题讨论】:

  • 您对 OOP 的定义与“安全”的语言和“不安全”的语言有什么关系?

标签: objective-c oop


【解决方案1】:

如果您查看 JavaScript 和许多其他 OO 语言(可能包括 PHP,但我不确定也不愿意猜测)的语义,您会发现这些语言提供了与 Objective C 通过指针提供的相同的间接性.事实上,这些语言在内部到处都使用指针。考虑一下这个(JavaScript)sn-p:

function f(obj) {
    obj.x = 1; // modifies the object referred to directly
    obj = {x: 2}; // doesn't affect caller
}
var foo = {x: 0};
f(foo); // passes a pointer/"reference"
// foo.x === 1

它大致相当于(C,因为我不知道 Objective C)这样的东西,模手动内存管理,静态类型等:

struct Obj { int x; };
void f(struct Obj *obj) {
    obj->x = 1;
    obj = ...; // you get the idea
}
struct Obj *foo = malloc(sizeof(*foo));
foo->x = 0;
f(foo);
free(foo);

它在 Objective C 中只是显式的,因为该语言是 C 的超集(100% 向后兼容和互操作性),而其他语言已经取消了显式指针并隐含了他们需要的间接。

【讨论】:

  • “基于”有点模糊。我经常把它读作 C 的“严格超集”,这可能更准确。
  • 所以你在这里说... f(foo) 在你的 javascript 部分。我们真的将指向 foo 对象的指针传递给函数吗?
  • @WilliamSham:嗯,它不像 C 中的指针(以及 Objective C)那样通用,因此可以使用替代术语“引用”。但基本上,是的。对象没有被复制,只有一个符号标记(指针,引用,地址,你想要什么都可以),它允许直接修改对象。
  • @delnan,谢谢。您如何解释这个概念实际上只是“指针”在起作用,参考 Ryan Wersal 关于实际“按值传递”和变量被复制的评论。
  • 嗯,这些指针是按值传递的(正如我的示例中的obj = ... 行所示,更改指针对调用者没有影响)。但是有些人认为这已经符合传递引用的条件,因为它允许修改对象(我不同意,但重要的是要意识到这个概念有很多名称)。 Pass-by-value 和-reference 是概念,而指针只是工具。通常在 C 中传递引用是通过将指针 传递给变量 来完成的。但是在 JS 中没有这样的东西,everything 是一个指向对象的指针。
【解决方案2】:

在 PHP 中,您也可以只使用指针但透明地工作。 你真的在使用对对象的引用

【讨论】:

    【解决方案3】:

    Objective-C 的设计者决定在所有 Objective-C 对象上使用指针的原因包括:

    1. 因此,他们可以在幕后处理内存管理,而不会剥夺程序员自己处理的能力。
    2. 对象的快速枚举。
    3. (也许是最重要的)赋予 id 类型能够传递 nil(null) 值而不会导致程序崩溃的能力。

    【讨论】:

      【解决方案4】:

      在这里建立其他答案:在 PHP 和其他语言中,您仍在使用指针。这就是为什么passing by reference 和按值传递之间仍然存在区别的原因。有几个很好的网站可以帮助explain the distinction,无论是语法还是通过任一方法传递的含义。


      编辑: 请参阅我帖子中的第二个链接。我对该信息的解释是 PHP 默认通过 value 传递。在函数调用期间在变量前面添加 & 号传递一个 reference(或者更确切地说是变量的地址)。本质上,通过引用传递是传递指针,而通过值传递则完全复制了值。它们的用法也有不同的含义(引用允许修改原始变量的值,甚至在函数范围之外等)。

      【讨论】:

      • 谢谢。这真的很有帮助。但就像这里的其他一些 cmets 说 PHP 实际上只使用指针一样,他们只是使引用隐式。是不是说当我“传值”的时候,其实还是变相的传“指针”?
      • 我更新了我的答案以解决您的问题。变相更直接地回答你的“指针”:不。如果按值传递是默认值,那么当您将值传递给函数时,您就是在复制该值。这些语言的隐含性质是,您可以在整个代码中使用指针,而无需关心它(至少在 Obj-C、C、C++ 等方面)。
      • 另一种说法是“按值传递引用”,这是因为正在复制对象的引用(指针)。
      【解决方案5】:

      Objective C 是 ANSI C 的严格超集和扩展,因此可以兼容地添加到语言中的本机类型受到限制(可能受到原始实现的限制)。但事实证明,这种与 ANSI C 的兼容性是混合使用 Objective C 和跨平台 C 代码重用的优势之一。

      顺便说一句,OOP 和“安全”几乎是正交的概念。它们在消耗 CPU 周期和/或消耗用户电池电量方面都有不同的潜在成本。

      【讨论】:

        【解决方案6】:

        对象是使用+alloc 方法创建的,该方法为堆上的新对象分配空间。在 C 中,因此在 Objective-C 中,引用堆上内存的唯一方法是通过指针。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-19
          相关资源
          最近更新 更多