@synthesize foo = _foo到底是什么?

时间:2023-01-14 09:12:35

Why does one want this underscore prefix in an iOS app?

为什么在iOS应用中需要这个下划线前缀?

4 个解决方案

#1


3  

Sometimes it helps to see whats happening behind the scenes to understand. Basically when you see this

有时候看看幕后发生的事情是有帮助的。基本上当你看到这个

@property (nonatomic, retain) Foo *foo;

With this in the implementation

有了这个在实施中

@synthesize foo=_foo;

It's syntax sugar for the following, meaning that the compiler basically generates this code for you

它是以下语法糖,意味着编译器基本上为您生成此代码

Foo *foo = nil;

-(Foo *) foo {
    return _foo;
}

-(void) setFoo:(Foo *)val {
    if( _foo != val ) {
        [_foo release];
        _foo = [val retain];
    }
}

This way when you refer to the public property, you hit it through the generated accessories of self.foo and if you want to refer to the instance variable inside your class you can refer to _foo. Before XCode four it was easy to get confused between the two. You could do something like

这种方式当你引用公共属性时,你通过生成的self.foo附件来命中它,如果你想在你的类中引用实例变量,你可以参考_foo。在XCode四之前,两者之间很容易混淆。你可以做点什么

self.foo = foo1;

foo = foo2;

This was perfectly legal and could cause problems on a couple levels. The second line doesn't use the accessor so foo2 would not be retained which could cause it to be picked up by garbage collection prematurely. Even worse, the second line doesn't use the accessor which would release any previous value meaning it would cause a memory leak.

这是完全合法的,可能导致几个级别的问题。第二行不使用访问器,因此不会保留foo2,这可能导致垃圾收集过早被拾取。更糟糕的是,第二行不使用会释放任何先前值的访问器,这意味着它会导致内存泄漏。

So in summary, the new technique creates a getter and setter for you property and allows you to also specify the name to be used for the instance variable, used for encapsulation.

总而言之,新技术为您的属性创建了一个getter和setter,并允许您指定用于实例变量的名称,用于封装。

#2


1  

Here's why I do this at times:

这就是我有时这样做的原因:

If I want to do lazy loading on a property I will typically underscore my ivar so that the work done to load the desired data from the back-end server/saved file/what-have-you is only loaded the first time. For example:

如果我想在属性上进行延迟加载,我通常会强调我的ivar,以便从后端服务器/保存文件加载所需数据的工作/只有你第一次加载。例如:

- (NSMutableArray *)recentHistory;
{
   if (_recentHistory == nil)
   {
       // Get it and set it, otherwise no work is needed... hooray!
   }

   return _recentHistory;
}

So here calls to the property [instanceOfClass recentHistory] (or instanceOfClass.recentHistory) will check the ivar to see if it needs to load the data or just return the already loaded data.

所以这里调用属性[instanceOfClass recentHistory](或instanceOfClass.recentHistory)将检查ivar以查看它是否需要加载数据或只返回已经加载的数据。

It is overkill to declare all of your properties this way.

以这种方式声明所有属性是过度的。

Hope that helps.

希望有所帮助。

#3


1  

just wanted to add my thoughts to all the above answers.

只想将我的想法添加到上述所有答案中。

in my case, i use it mainly to keep my classes safe from accidents.

在我的情况下,我主要用它来保证我的课程免受意外伤害。

in my .h files, i declare only the properties with no ivars. in the .m file, i use the above @synthesize pattern to hide the actual ivar from users, including myself, to be forced to use the synthesized/dynamic accessors and not the otherwise ivars directly. you could use anything for your ivar name and not just underscore it. e.g. you could do:

在我的.h文件中,我只声明没有ivars的属性。在.m文件中,我使用上面的@synthesize模式来隐藏用户(包括我自己)的实际ivar,以强制使用合成/动态访问器,而不是直接使用其他ivars。你可以使用任何东西作为你的ivar名称,而不仅仅是强调它。例如你可以这样做:

@synthesize foo = _mySecretFoo;
@synthesize bar = oneUglyVarBecauseIHateMyBoss;

this way, your boss would only see bar, and you would find it much easier, and thus safer, to use the bar accessor - whether you use dot notation or messages.

通过这种方式,您的老板只会看到bar,并且您会发现使用条形码访问器更容易,也更安全 - 无论您使用点符号还是消息。

i prefer this approach over the other,

我更喜欢这种方法,

@property (getter=foo, setter=setFoo, ...) _mySecretFoo;
@property (getter=bar, setter=setBar, ...) oneUglyVarBecauseIHateMyBoss;

as this does not enforce private implementation and encapsulation, and it's just extra typing when Xcode can do the same for you. one thing to remember, properties are not the same as ivars! you could have more properties than ivars, or the other way around.

因为这不会强制执行私有实现和封装,而且当Xcode可以为您执行相同操作时,它只是额外的输入。有一点要记住,属性与ivars不一样!你可以拥有比ivars更多的属性,或者反过来。

#4


0  

it's a convention to keep the ivar (instance variables) safe, so you can only access it through the getter and setter.

保持ivar(实例变量)安全是一种惯例,因此您只能通过getter和setter访问它。

#1


3  

Sometimes it helps to see whats happening behind the scenes to understand. Basically when you see this

有时候看看幕后发生的事情是有帮助的。基本上当你看到这个

@property (nonatomic, retain) Foo *foo;

With this in the implementation

有了这个在实施中

@synthesize foo=_foo;

It's syntax sugar for the following, meaning that the compiler basically generates this code for you

它是以下语法糖,意味着编译器基本上为您生成此代码

Foo *foo = nil;

-(Foo *) foo {
    return _foo;
}

-(void) setFoo:(Foo *)val {
    if( _foo != val ) {
        [_foo release];
        _foo = [val retain];
    }
}

This way when you refer to the public property, you hit it through the generated accessories of self.foo and if you want to refer to the instance variable inside your class you can refer to _foo. Before XCode four it was easy to get confused between the two. You could do something like

这种方式当你引用公共属性时,你通过生成的self.foo附件来命中它,如果你想在你的类中引用实例变量,你可以参考_foo。在XCode四之前,两者之间很容易混淆。你可以做点什么

self.foo = foo1;

foo = foo2;

This was perfectly legal and could cause problems on a couple levels. The second line doesn't use the accessor so foo2 would not be retained which could cause it to be picked up by garbage collection prematurely. Even worse, the second line doesn't use the accessor which would release any previous value meaning it would cause a memory leak.

这是完全合法的,可能导致几个级别的问题。第二行不使用访问器,因此不会保留foo2,这可能导致垃圾收集过早被拾取。更糟糕的是,第二行不使用会释放任何先前值的访问器,这意味着它会导致内存泄漏。

So in summary, the new technique creates a getter and setter for you property and allows you to also specify the name to be used for the instance variable, used for encapsulation.

总而言之,新技术为您的属性创建了一个getter和setter,并允许您指定用于实例变量的名称,用于封装。

#2


1  

Here's why I do this at times:

这就是我有时这样做的原因:

If I want to do lazy loading on a property I will typically underscore my ivar so that the work done to load the desired data from the back-end server/saved file/what-have-you is only loaded the first time. For example:

如果我想在属性上进行延迟加载,我通常会强调我的ivar,以便从后端服务器/保存文件加载所需数据的工作/只有你第一次加载。例如:

- (NSMutableArray *)recentHistory;
{
   if (_recentHistory == nil)
   {
       // Get it and set it, otherwise no work is needed... hooray!
   }

   return _recentHistory;
}

So here calls to the property [instanceOfClass recentHistory] (or instanceOfClass.recentHistory) will check the ivar to see if it needs to load the data or just return the already loaded data.

所以这里调用属性[instanceOfClass recentHistory](或instanceOfClass.recentHistory)将检查ivar以查看它是否需要加载数据或只返回已经加载的数据。

It is overkill to declare all of your properties this way.

以这种方式声明所有属性是过度的。

Hope that helps.

希望有所帮助。

#3


1  

just wanted to add my thoughts to all the above answers.

只想将我的想法添加到上述所有答案中。

in my case, i use it mainly to keep my classes safe from accidents.

在我的情况下,我主要用它来保证我的课程免受意外伤害。

in my .h files, i declare only the properties with no ivars. in the .m file, i use the above @synthesize pattern to hide the actual ivar from users, including myself, to be forced to use the synthesized/dynamic accessors and not the otherwise ivars directly. you could use anything for your ivar name and not just underscore it. e.g. you could do:

在我的.h文件中,我只声明没有ivars的属性。在.m文件中,我使用上面的@synthesize模式来隐藏用户(包括我自己)的实际ivar,以强制使用合成/动态访问器,而不是直接使用其他ivars。你可以使用任何东西作为你的ivar名称,而不仅仅是强调它。例如你可以这样做:

@synthesize foo = _mySecretFoo;
@synthesize bar = oneUglyVarBecauseIHateMyBoss;

this way, your boss would only see bar, and you would find it much easier, and thus safer, to use the bar accessor - whether you use dot notation or messages.

通过这种方式,您的老板只会看到bar,并且您会发现使用条形码访问器更容易,也更安全 - 无论您使用点符号还是消息。

i prefer this approach over the other,

我更喜欢这种方法,

@property (getter=foo, setter=setFoo, ...) _mySecretFoo;
@property (getter=bar, setter=setBar, ...) oneUglyVarBecauseIHateMyBoss;

as this does not enforce private implementation and encapsulation, and it's just extra typing when Xcode can do the same for you. one thing to remember, properties are not the same as ivars! you could have more properties than ivars, or the other way around.

因为这不会强制执行私有实现和封装,而且当Xcode可以为您执行相同操作时,它只是额外的输入。有一点要记住,属性与ivars不一样!你可以拥有比ivars更多的属性,或者反过来。

#4


0  

it's a convention to keep the ivar (instance variables) safe, so you can only access it through the getter and setter.

保持ivar(实例变量)安全是一种惯例,因此您只能通过getter和setter访问它。