【问题标题】:difference between a variable with and without an underscore in objective-c [duplicate]Objective-c中带和不带下划线的变量之间的区别[重复]
【发布时间】:2013-12-16 11:41:42
【问题描述】:

在我下面的教程中,它创建了一个像这样的数组的属性

@property (nonatomic, retain) NSMutableArray *entries;

并在实现文件中定义它定义为...

 entries = [[NSMutableArray alloc] init];

但是在我的程序中,这样定义会给我一个错误

“使用未声明的标识符‘entries’;你的意思是‘_entries’吗?”

这会影响我的程序吗?

【问题讨论】:

标签: objective-c


【解决方案1】:

简单来说:

@property (nonatomic, retain) NSMutableArray *entries;

为您创建以下代码:

一个名为 _entries 的 ivar 和两个方法

- (void)setEntries:(NSMutableArray *)entries;
- (NSMutableArray *)entries;

如果你想给 ivar 一个不同的名字(例如 entries 不带下划线)你必须合成它们。但是您几乎不需要实际的,只需使用您的属性,例如 self.entries

您真正需要 ivar 的极少数情况是您想要覆盖 setter 和 getter 方法

- (void)setEntries:(NSMutableArray *)entries
{
    _entries = entries;
    // do more stuff
}

【讨论】:

  • 你通常也会在 init / dealloc 中使用 ivar
  • 你愿意吗?为什么?我总是使用这些属性。
  • 它主要是为了避免 KVO 的副作用(当对象被初始化或释放时,观察者可能还没有准备好处理通知)
  • @wattson12 但是,有时您希望它发生。一般来说,这更多是关于个人品味和了解你在做什么。
  • @Sulthan 非常正确,有时您会使用 ivars 来避免 KVO 触发,但我认为这是避免奇怪行为的一个很好的一般规则(但这可能只是我的口味......)跨度>
【解决方案2】:

当您声明属性时,编译器创建私有变量,您可以使用下划线 (_entries) 访问该变量,并且编译器还创建 setter(如果您未指定只读)和 getter。您可以通过两种方式调用 getter:

[self entries] or self.entries

当您声明属性时,您应该通过两种方式访问​​它:

_entries - 你可以直接访问你的私有变量(可以在类中使用)

self.entries - 您可以安全地访问此属性视图 setter/getter,因为此方法管理如何访问它(释放、保留、复制等)

【讨论】:

    【解决方案3】:

    @property (nonatomic, retain) NSMutableArray *entries; 只是名称为_entries 的实例变量。 (或任何其他名称,您可以在进行合成时指定)

    当您执行@synthesize entries 时,会为您创建两个访问器方法(setter 和 getter)
    - (void)setEntries:(NSMutableArray *)entries;
    - (NSMutableArray *)entries;

    如果您直接以_entries 访问它,那么它只是在更改变量的值。 但是如果你说 self.entries,就会调用访问器方法。访问器方法是根据您指定的属性类型创建的,strong(或retaincopyassignatomic,比如assign 只会将值复制到变量,atomic 确保如果 setter 和 getter 从不同的线程一起调用,getter 总是在 setter 开始之前或 setter 完成之后获取值。

    【讨论】:

    • 这不是一个很好的描述。属性不是实例变量。属性是两个方法的集合,在大多数情况下(但不总是)由实例变量支持。
    • 并非总是如此?什么时候不是实例变量?
    • 随心所欲。例如,Core Data 管理对象的托管属性。属性是一组一个或两个方法(getter 和可能的 setter)。合成表示属性的变量只是可选的。
    • 如果你不合成,我认为你不会得到iOS为你制作的setter和getter。而且我仍然认为它是一个实例变量。 developer.apple.com/library/ios/documentation/cocoa/conceptual/… 这提到“大多数”由实例变量支持,然后在里面说“读写”由实例变量支持。 (还有managed properties for Core Data management objects,那是什么?
    • 首先,setter & getter 不是系统生成的(iOS),它们是编译器在你@synthesize时生成的。然而,当你有一个没有 setter 和 getter 的属性时,还有一个 @dynamic 选项(也没有 ivar,参见核心数据)。此外,您可以自己编写方法,无需任何 ivar。 ivar 的情况只是属性的一种可能用法。我再说一遍,你不明白什么是属性。属性不需要 ivars。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2014-03-13
    • 2011-10-19
    • 1970-01-01
    • 2012-10-11
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多