【问题标题】:What is the -> operator doing in -copyWithZone:? [duplicate]-copyWithZone: 中的 -> 运算符在做什么? [复制]
【发布时间】:2012-09-16 09:11:43
【问题描述】:

可能重复:
Arrow operator (->) usage in C
Dot (“.”) operator and arrow (“->”) operator use in C vs. Objective-C

我是一名新手,正在查看最近一次更新于 2008 年的免费软件/开源程序,但我无法识别以下符号中的 ->

- (id)copyWithZone:(NSZone *)zone
{
  GFIPGeniusItem * newItem = [[[self class] allocWithZone:zone] init];
  newItem->_stringValue = [_stringValue copy];
  newItem->_imageURL = [_imageURL copy];
  newItem->_webResourceURL = [_webResourceURL copy];
  newItem->_speakableStringValue = [_speakableStringValue copy];
  newItem->_soundURL = [_soundURL copy];
  return newItem;
}

我假设它允许某种捷径,但我很想具体说明它的作用。

【问题讨论】:

  • 不是骗子。它的语义和约定都与 C 中的不同。

标签: objective-c ios


【解决方案1】:

这是一种从对象外部直接访问 ObjC 对象内的实例变量的方法。 (语法和-> 是从C 结构中借用的,表现得好像引用是一个指向结构的指针)。

这种访问机制在这一点上几乎是退化的,并且在现代 ObjC 代码中非常罕见,因为良好的封装需要使用访问器和属性,而不是直接接触实例变量。不过,在一些非常特殊的情况下它是合法的,这就是其中之一:

复制对象时,您希望获得与当前self 的状态完全匹配的结果副本。实现此目的的最简洁方法通常是显式设置副本的 ivars,以防止 init 重载或访问器可能导致的任何副作用。它是“安全的”,因为执行它的代码仍然位于有问题的类中,因此如果您需要更改或添加 ivars,您也可以使用可能需要的任何其他知识来更新此代码。

在有问题的班级之外这样做是不好的形式,没有充分的理由这样做。

【讨论】:

  • 嗯,在现代 ObjC 代码的最底层仍然可以看到它。但是,除非您正在移植 Cocoa 或 gnustep,否则您很少需要编写甚至阅读该级别的代码。 (话虽如此,几年前我确实使用过它,构建自定义 DO 风格的代理,它必须以相同的方式与经典和现代运行时一起工作。)
  • 非常感谢——非常感谢。
【解决方案2】:

在 Objective-C 中,您有某种两种变量类型的访问器。每个人都应该知道的是"." 之一(例如 Class.variable)。此类型调用适当的 getter 或 setter。

现在,另一种类型 - 您要求的类型 - 用于课堂使用。显然,当 getter 或 setter 使用 "." 表示法自动调用时,您需要一种不使用 setter 来设置变量的方法(在 setter 本身中调用 setter 会导致无限循环)。因此,使用"->" 表示法-> 简单地说,它是直接访问模式。

通常,Objective-C 两种表示法的变量名是相同的,但有些人更喜欢使用以"_" 开头的类内表示法变量名。这是通过将@synthesize variable 行编辑为@synthesize variable = _variable 来实现的。

【讨论】:

    【解决方案3】:

    这是一个指针间接运算符。 a->b(*a).b 的含义相同(其中. 是结构成员访问运算符,而不是Objective-C 的属性点语法)。

    当你说:

    newItem->_stringValue
    

    您正在直接访问 newItem 指向的对象的 _stringValue 实例变量。

    -> 运算符在 C++ 中很常见,但在 Objective-C 中并不常见。

    【讨论】:

      【解决方案4】:

      在 Objective C 中,与在 C++ 中一样,p->m 表示法等价于 (*p).m,即取消引用指向基类型的指针,然后调用相应的方法或属性。

      所以在你的情况下,使用其他符号它看起来像这样:

      (*newItem)._stringValue = [_stringValue copy];
      

      (使用 -> 操作符更常见)

      【讨论】:

      • 然而,另一个符号在 objc 中是无效的,因为你不能取消引用一个对象。我很惊讶这些答案都没有提出来。
      • 其实还是这样吗?据我所知,gcc 和 clang 都允许您取消引用对象指针。您不能在 ObjC 中存储或传递结果,但在 ObjC++ 中,您可以将其粘贴到 Foo&(或 auto)中。 (*f).x 似乎与 f->x 做同样的事情,而在 C++ 中,如果你这样做 Foo& g=*f,它会在 g.x 做同样的事情。这可能会混淆 ARC(尚未测试),但除此之外它似乎有效。当然,即使它碰巧在 Apple 的两种实现中都有效,它也可能是非法的,但这让我很好奇,提出了语言在哪里说它是无效的问题。
      猜你喜欢
      • 2013-03-29
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多