【问题标题】:Is the NSObject code below redundant?下面的 NSObject 代码是多余的吗?
【发布时间】:2015-08-18 18:45:41
【问题描述】:

我在这里学习教程:http://blog.soff.es/archiving-objective-c-objects-with-nscoding 创建一个可以在回合制游戏中保存我的比赛数据的 NSObject。

但是我在 .m 文件中收到此警告:

Autosynthesized property 'title' will use synthesized instance variable '_title', not existing instance variable 'title'

所以我的问题是如果(在下面的代码中)我删除括号之间的代码会丢失一些重要的东西吗?

 @interface Note : NSObject <NSCoding> {
  NSString *title;
  NSString *author;
  BOOL published; 
 }

 @property (nonatomic, copy) NSString *title;
 @property (nonatomic, copy) NSString *author;
 @property (nonatomic) BOOL published;

 @end

【问题讨论】:

  • 据我所知,只要照顾得当,不会有任何问题。
  • 如果需要访问title的getter和setter方法,需要使用@prop *title。
  • 是的。这是多余的。您正在遵循一个非常古老的教程,当时,这被认为是编码的方式。现在 ivars 和 properties 有不同的用途。见stackoverflow.com/questions/843632/…
  • 这不是多余的,它是一个可以让你头疼的大陷阱。例如,此代码创建一个带有匹配实例变量 _title 的属性标题,以及一个名为 title 的完全不相关的实例变量。所以 self.title = @"this";并且 title = @"that" 设置了两个不同的实例变量。

标签: ios objective-c nsobject nscoding


【解决方案1】:

您不应该显式声明 ivars,因为属性会自动合成自己的 ivars,但名称略有不同。显式 ivars 没有意义,不会被属性使用。当您打算设置属性时错误地使用 ivars 时,拥有它们只会导致错误。

警告通过让您知道会有两个相似的 ivars 来指出这一点。

您的代码应该是:

 @interface Note : NSObject <NSCoding>

 @property (nonatomic, copy) NSString *title;
 @property (nonatomic, copy) NSString *author;
 @property (nonatomic) BOOL published;

 @end

这样可以避免以下错误:

title = @"Some Title"; // sets your ivar, not the property

相对于:

_title = @"Some Title"; // directly sets the property's ivar

当然你应该使用这个属性:

self.title = @"Some Title"; // uses the property methods

【讨论】:

  • Autosynthesize 使用声明的 ivars,如果它找到一个合适的名称。除此之外,还有声明 ivars 的原因。
  • @AminNegm-Awad 是的,声明 ivars 本身就很好。但是你不应该为属性声明 ivars。只为不基于属性的变量声明 ivars。
  • @AminNegm-Awad 为什么投反对票?如警告所述,该属性将用下划线合成 ivar。属性将使用显式声明的 ivars,除非您添加 @synthesize title,例如。
  • 1.我总是谈论属性的 ivars。一个用例是在内部有一个可变的子类。合成将为您提供不可变的基类。 2. 否决“你不应该显式声明 ivars,因为属性会自动合成它们自己的 ivars”这是不正确的。
  • @rmaddy 感谢您的回答。作为后续问题,我如何发送此对象中的数据?
【解决方案2】:

您会丢失实例变量,但您并不真正想要它们,因为属性会为您创建它们(名称略有不同),并且通过属性访问器方法。

【讨论】:

    【解决方案3】:

    是的,而且很可能你得到了你不想要的东西。

    如果您没有标识符为 identifier 或标识符为 _identifier 的实例变量,手动合成和自动合成将创建一个具有姓名_identifier

    如果您已经有一个标识符为 _identifier 的实例变量,手动合成和自动合成将使用它。 (因此在大多数情况下,声明这样一个实例变量是没有意义的。)

    但是如果你有一个标识符为 identifier 的实例变量(没有下划线)手动合成将使用它,而自动合成将不使用它,而是创建一个标识符为 _identifier。因此,您有两个实例变量 identifier_identifier。通常你不希望这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-29
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 2018-04-14
      • 1970-01-01
      相关资源
      最近更新 更多