【问题标题】:Why are there only sometimes compiler errors when accessing a property without self?为什么在访问没有 self 的属性时有时会出现编译器错误?
【发布时间】:2013-04-10 17:16:55
【问题描述】:

我注意到在某些旧版本的 Xcode 中,您可以使用没有self 的对象属性就可以了。 现在,当我尝试在没有 self 的情况下访问我的属性时,它给了我一个错误,但是今天我正在编写这段代码,它工作正常,并且没有给我任何错误。

[aCoder encodeObject:itemName forKey:@"itemName"];

为什么会这样?为什么在这种情况下我不会收到错误消息?为什么在其他情况下会引发错误?这个行为为什么不能统一,应该怎么用?

【问题讨论】:

    标签: objective-c compiler-errors declared-property


    【解决方案1】:

    没有self,您永远无法访问属性。如果您没有使用self,那么您将直接访问与属性同名的实例变量。这给许多开发者带来了无穷无尽的问题。

    这就是为什么最新的编译器(在最新版本的 Xcode 中)生成带有前导下划线的属性 ivars。这样,如果您在尝试访问该属性时忘记使用self,则会收到错误消息,因为没有同名的 ivar。

    为了统一您的体验,您应该在较旧的编译器中使用以下模式:

    定义@property int foo;。然后定义 ivarint _foo。然后使用@synthesize foo = _foo;

    使用较新的编译器,您只需声明 @property int foo 即可。编译器会为你生成 ivar int _foo

    在这两种情况下,您都使用 self.foo 作为属性,使用 _foo 直接访问 ivar。

    【讨论】:

      【解决方案2】:

      每当您使用新的 LLVM 编译器创建属性时,它都会创建一个名为 _property 的 ivar。

      如果您不覆盖 auto-synthesized,则需要使用 _propertyself.property

      在您的情况下,您似乎使用的是旧编译器(即带有 XCode4.3 bacwards),或者您已将自动合成覆盖为:

      @synthesize aCoder;
      

      【讨论】:

        【解决方案3】:

        我假设你的意思是这个警告:

        许多项目在其构建设置中没有启用许多警告,因此这可能是您没有看到此警告的原因之一。

        还有一些方法是常见的直接访问实例变量,Xcode会忽略直接的ivar访问;这些包括 init*dealloc 方法(但不幸的是不是 getter/setter 方法)。

        【讨论】:

        • 对不起,这不正确。您可以通过任何方法直接访问 ivars 或访问属性。 Xcode 不关心任何一种方式(编译器也不关心)。
        • 编译器确实在乎,只是大多数人不会启用很多警告。如果你喜欢使用 -Wall 和新的 -Weverything 之类的东西,你会收到这样的警告:i.imgur.com/II4vGFw.png?1?3012
        • 谢谢。我以前没见过。您是说启用此功能后,除init*dealloc 之外的所有地方都会出现警告?
        • 是的。唯一烦人的事情是,覆盖 setter 和 getter 并直接访问实例变量(如您所愿)仍然会触发警告。你现在必须添加一个编译指示来避免这种情况。
        【解决方案4】:

        如果你在一个类中定义属性并且@synthesize它们使用相同的命名,那么你可以不使用self访问它们

        例如

        在.h中

        @property(nonatomic, copy) NSString *str1;
        

        在.m

        @synthesize str1 = str1;
        
        str1 = @"hello";
        self.str1 = @"hello"; // Or this
        

        如果您不使用显式 @synthesize,那么 XCode 会自动使用 @synthesize property = _property(最近),因此您可以执行以下操作

        在.h中

        @property(nonatomic, copy) NSString *str1;
        

        在.m

        _str1 = @"hello";
        self._str1 = @"hello"; // Or this
        

        如果属性是在父类中定义的,您将无法使用self。您必须在当前的课程中进行综合才能使用它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-10
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          • 2013-08-14
          • 1970-01-01
          相关资源
          最近更新 更多