何时在类属性上使用self?

时间:2022-01-03 13:18:05

When is self needed for class properties? For example:

类属性何时需要?例如:

self.MyProperty = @"hi there";

vs

MyProperty = @"hi there";

MyProperty is an NSString set as (nonatomic, copy). Is there any difference in memory management for the above two?

MyProperty是一个NSString设置为(非原子,复制)。上述两种内存管理有什么不同吗?

What about when there is no property and the variable MyProperty is declared in the header file? Is a property needed if it is never referenced outside of the class? Does it make a difference to memory management?

什么时候没有属性,并且在头文件中声明了变量MyProperty?如果它从未被引用到类之外,是否需要属性?它对内存管理有所影响吗?

8 个解决方案

#1


Yes, there is a difference for both memory and performance.

是的,内存和性能都有所不同。

MyProperty = @"hi there";

This is considered a direct assignment. There is practically no memory or performance impact. Of course, that's not to say it's best practice - that's a different question :)

这被认为是直接分配。实际上没有内存或性能影响。当然,这并不是说这是最佳实践 - 这是一个不同的问题:)

@property(nonatomic, copy) NSString *MyProperty;
// ...
self.MyProperty = @"hi there";

This statement has a significant impact on memory and performance. This is essentially equivalent to:

此声明对内存和性能有重大影响。这基本上相当于:

-(void)setMyProperty(NSString *)newValue {
    if (MyProperty != newValue) {
        [MyProperty release];
        MyProperty = [newValue copy];
    }
}

The old value is released and the new value is copied into MyProperty. This is acceptable and especially typical when dealing with strings when the string your assigning is mutable (ie, it could change later).

旧值将被释放,新值将复制到MyProperty中。当你的赋值字符串是可变的(即,它可能在以后改变)时处理字符串时,这是可以接受的。

If, as in your example, you're simply assigning a static string (@"hi there"), there is nothing wrong with directly assigning the string value; it's more efficient however the difference in performance is trivial.

如果在你的例子中,你只是简单地指定一个静态字符串(@“hi there”),那么直接分配字符串值没有错;它的效率更高,但性能上的差异是微不足道的。

You can declare a property with @property as retain, copy, or assign (default is assign). You can then generate "accessor" (getter/setter) methods by using @synthesize. Here is what the setter methods look like that are generated when you do so:

您可以将@property的属性声明为retain,copy或assign(默认为assign)。然后,您可以使用@synthesize生成“访问器”(getter / setter)方法。以下是执行此操作时生成的setter方法的外观:

// @property(nonatomic, assign)
-(void)setMyProperty(NSString *)newValue {
    MyProperty = newValue;
}

// @property(nonatomic, retain)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue retain];
    }

// @property(nonatomic, copy)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue copy];
    }
}

More information on ObjectiveC Declared Properties.

有关ObjectiveC声明的属性的更多信息。

"You can use the @synthesize and @dynamic directives in @implementation blocks to trigger specific compiler actions. Note that neither is required for any given @property declaration.

“您可以在@implementation块中使用@synthesize和@dynamic指令来触发特定的编译器操作。请注意,任何给定的@property声明都不需要。

Important: If you do not specify either @synthesize or @dynamic for a particular property, you must provide a getter and setter (or just a getter in the case of a readonly property) method implementation for that property."

要点:如果没有为特定属性指定@synthesize或@dynamic,则必须为该属性提供getter和setter(或者只是readonly属性的getter)方法实现。“

In other words, if you declare a property but don't synthesize the property, you won't be able to use [self MyProperty] or self.MyProperty unless you define 'MyProperty' and 'setMyProperty' methods. If you don't declare a property then you simply have an instance variable.

换句话说,如果声明属性但不合成属性,除非定义“MyProperty”和“setMyProperty”方法,否则将无法使用[self MyProperty]或self.MyProperty。如果您没有声明属性,那么您只需要一个实例变量。

Note: @dynamic doesn't generate the accessors. It's really used if you're dynamically (ie, magically) resolving accessor methods via loading code or dynamic method resolution.

注意:@dynamic不会生成访问者。如果你通过加载代码或动态方法解析动态地(即,神奇地)解析访问器方法,它就真的被使用了。

#2


The difference is that

不同之处在于

self.MyProperty = @"hi there"

is dot-notation call that will call the generated accessor, which will handle the retain counts correctly (equivalent to [self setMyProperty:@"hi there"]), whereas

是点符号调用,它将调用生成的访问器,它将正确处理保留计数(相当于[self setMyProperty:@“hi there”]),而

MyProperty = @"hi there"

is a direct assignment to your member variable, which doesn't release the old value, retain the new one, or do anything else your accessor does (e.g., if you have a custom setter that does extra work).

是对您的成员变量的直接赋值,它不会释放旧值,保留新值或执行您的访问者所做的任何其他操作(例如,如果您有自定义setter执行额外工作)。

So yes, there is a big difference in memory management and in behavior in general between the two. The latter form is almost always wrong, unless you know specifically why you are doing it and that you are handling the retain counts correctly yourself.

所以,是的,内存管理和两者之间的行为存在很大差异。后一种形式几乎总是错误的,除非您明确知道为什么要这样做,并且您自己正确处理保留计数。

#3


If you use automatic Key-Value Observing (or any Cocoa technology that builds on it - like bindings, ...), it is also important use the setter. The observer would not receive any notification if you assign to the ivar. If you bind "MyProperty" to a NSTextfield and you change your "MyProperty" ivar via code, the bound textfield would still display the old value as it did not receive any change notification.

如果您使用自动键值观察(或基于它的任何Cocoa技术 - 如绑定,......),使用setter也很重要。如果您分配给ivar,观察员将不会收到任何通知。如果将“MyProperty”绑定到NSTextfield并通过代码更改“MyProperty”ivar,则绑定的文本字段仍会显示旧值,因为它没有收到任何更改通知。

#4


To access a variable, there is often no need to use the dot notation. Thus, in code generated by the XCode templates, you will see things like:

要访问变量,通常不需要使用点表示法。因此,在XCode模板生成的代码中,您将看到以下内容:

[flipsideViewController viewWillAppear:YES];

There is no need to write self.flipsideViewController here, because the accessor method typically does nothing except handing you the variable.

这里没有必要编写self.flipsideViewController,因为除了处理变量之外,访问器方法通常什么都不做。

So a good rule of thumb is to use dot notation when you are setting a variable (absolutely necessary unless you want to do your own retaining and releasing), but not when you're accessing it:

因此,一个好的经验法则是在设置变量时使用点符号(绝对必要,除非您想要自己保留和释放),但不是在您访问它时:

self.aString = @"Text text text";
NSLog (aString);   // No need for self.aString here
NSString* tmpString = aString; // Here neither

When you're using non-object types, like int or float or many others, you can get away with not using the dot notation/setter method. In these cases, there is nothing to retain, so the setter method will do little apart from just assigning the value.

当您使用非对象类型(如int或float或许多其他类型)时,您可以不使用点符号/ setter方法。在这些情况下,没有什么可以保留,因此setter方法除了分配值之外几乎没有什么作用。

However, synthesized getters and setters do more than just retaining and releasing. As others have mentioned, they are also the engine that keeps the KVO system running. Thus, you should use the proper setters even on ints, floats and the rest.

然而,合成的吸气剂和固定剂不仅仅是保留和释放。正如其他人所提到的,它们也是保持KVO系统运行的引擎。因此,即使在整数,浮点数和其余部分上也应该使用适当的设定器。

What about the accessors then? In more advanced contexts, a class might respond to a request for a variable's value even when the variable doesn't exist. To quote the exalted Objective-C manual, classes might provide "method implementations directly or at runtime using other mechanisms [than simple accessor methods] such as dynamic loading of code or dynamic method resolution."

那么访问者呢?在更高级的上下文中,即使变量不存在,类也可能响应对变量值的请求。为了引用高级的Objective-C手册,类可以直接或在运行时使用其他机制[而不是简单的访问器方法]提供“方法实现”,例如动态加载代码或动态方法解析。

(One way of implementing this sort of on-the-fly response to messages is by overriding NSObject methods like methodSignatureForSelector: and forwardInvocation: .)

(实现对消息的这种即时响应的一种方法是重写NSObject方法,如methodSignatureForSelector:和forwardInvocation:。)

For this reason, using properly declared interfaces (whether synthesized or not) is always a good idea when you're working on something big. But it's completely ok to access ivars directly, as long as you set them using the proper API.

出于这个原因,使用正确声明的接口(无论是否合成)总是一个好主意,当你在做大事。但只要您使用适当的API设置它们,就可以直接访问ivars。

(Note: I'm not a Cocoa guru, so corrections are more than welcome.)

(注意:我不是可可大师,因此非常欢迎更正。)

#5


For the second part of the question, property definition is not needed, it is a help to us . The @synthesize directive on property generates accessor methods for properties so we don't have to do it manually, and because:

对于问题的第二部分,不需要属性定义,这对我们有帮助。属性上的@synthesize指令为属性生成访问器方法,因此我们不必手动执行,因为:

This code instructs the compiler to generate, or synthesize, the accessor methods. The compiler will generate the accessor methods using well-tested, fast algorithms that are ready for multi-core and multi-threaded environments, including locking variables in setter methods. Not only does using properties reduce the amount of code that you have to write, it replaces that code with the best possible accessors for today's modern multi-core systems. Later, if you need to provide an alternative implementation for a property accessor, you can simply add the appropriate code to your class.

此代码指示编译器生成或合成访问器方法。编译器将使用经过充分测试的快速算法生成访问器方法,这些算法已准备好用于多核和多线程环境,包括在setter方法中锁定变量。使用属性不仅减少了您必须编写的代码量,而且还使用当今现代多核系统的最佳访问器替换了该代码。稍后,如果您需要为属性访问器提供替代实现,则只需将适当的代码添加到您的类中即可。

http://developer.apple.com/leopard/overview/objectivec2.html

The nonatomic will avoid use of locking when accessing variables, if you don't specify anything then default is atomic. Locking is useful on multithreaded systems. The copy specifies what code should be generated for accessors, copy will copy the object, retain will retain new object and release old one, assign is good for simple variables like int to just plain assign values. So when you define your property as you did above (nonatomic,copy) and then use self.MyProperty = @"Hey" you're actually calling generated accessor that will make a copy of the new variable as opposed to just assigning it. You can override accessor and add checking to it.

非原子会在访问变量时避免使用锁定,如果你没有指定任何东西,那么默认是原子的。锁定在多线程系统上很有用。副本指定应为访问器生成什么代码,copy将复制对象,retain将保留新对象并释放旧对象,赋值对于简单的变量(如int)只是简单赋值。因此,当你像上面那样定义你的属性(非原子,复制),然后使用self.MyProperty = @“嘿”你实际上调用生成的访问器,它将创建新变量的副本而不是仅仅分配它。您可以覆盖访问者并向其添加检查。

Because of the above I would say that defining property has benefits even when the variable is not used outside of the class.

由于上述原因,我会说定义属性即使在类之外没有使用变量也有好处。

I believe to access properties you should use self.MyProperty instead of just MyProperty but I can't point you to explanation why. Might be something to do with the fact that compiler will generate from

我相信访问属性你应该使用self.MyProperty而不仅仅是MyProperty,但我不能指出你解释原因。可能与编译器将生成的事实有关

self.MyProperty = @"Hey";

this:

[self setMyProperty: @"Hey"];

But I'm only speculating here.

但我只是在这里猜测。

Whether you call self.MyProperty or MyProperty it should not affect memory management (I would still prefer the first - self.MyProperty).

无论你是调用self.MyProperty还是MyProperty它都不应该影响内存管理(我还是更喜欢第一个 - self.MyProperty)。

See Objective-C 2.0 Overview for some high level description from Apple.

有关Apple的一些高级描述,请参阅Objective-C 2.0概述。

#6


As a supplement to the other answers, try to think of it this way:

作为其他答案的补充,尝试以这种方式思考:

self.MyProperty = @"hi there";

or

[self setMyProperty:@"hi there"];

(which are equivalent) both call a method, whereas

(相当于)都调用方法,而

MyProperty = @"hi there";

Simply sets a variable.

只需设置变量即可。

#7


This is an old question, though it used to be "When do I write [self setMyProperty:@"hi there"]?" (Note that self.MyProperty = @"hi there" is exactly equivalent to this.)

这是一个老问题,虽然它曾经是“我什么时候写[self setMyProperty:@”hi there“]?” (注意self.MyProperty = @“hi there”与此完全相同。)

The answer I've always heard (and which makes good sense) is always use the accessor; never write MyProperty = @"hi there". There are several reasons:

我一直听到的答案(而且很有道理)总是使用访问器;永远不要写MyProperty = @“hi there”。有几个原因:

  1. Memory management is handled for you; you don't have to worry about proper retaining/releasing/copying.
  2. 内存管理是为您处理的;你不必担心正确的保留/释放/复制。

  3. It's easier to modify your code in the future; if at some point you realize that changing MyProperty needs to have a particular side effect, you can add to the setter method without finding every time you set MyProperty.
  4. 将来修改代码会更容易;如果在某些时候您意识到更改MyProperty需要具有特定的副作用,您可以添加到setter方法而不会在每次设置MyProperty时找到。

  5. If you ever have problems with MyProperty, it's easy to add logging code to the setter (or even getter) to find out every time it's changed (or even accessed).
  6. 如果您遇到MyProperty问题,可以轻松地将记录代码添加到setter(甚至是getter),以便在每次更改(甚至访问)时找到它们。

Summary: it's safest and most flexible to always use [self setMyProperty:@"hi there"] or self.MyProperty = @"hi there", and never use MyProperty = @"hi there".

总结:总是使用[self setMyProperty:@“hi there”]或self.MyProperty = @“hi there”是最安全和最灵活的,并且从不使用MyProperty = @“hi there”。

#8


Still not clear on when to use the accessors and when to do direct assignment on ivars ? I have seen lot of Apple examples which directly access the ivars. So using properties for all ivars seems pedantic overkill.

还不清楚何时使用访问器以及何时在ivars上进行直接分配?我见过许多直接访问ivars的Apple示例。所以使用所有ivars的属性似乎是迂腐的矫枉过正。

It seems only significant ivars which need to be around longer and are accessed outside tend to use the properties.

似乎只有重要的ivars需要更长时间并且在外部访问倾向于使用属性。

Would appreciate some Cocoa gurus to step in and clarify.

希望一些可可大师介入并澄清。

#1


Yes, there is a difference for both memory and performance.

是的,内存和性能都有所不同。

MyProperty = @"hi there";

This is considered a direct assignment. There is practically no memory or performance impact. Of course, that's not to say it's best practice - that's a different question :)

这被认为是直接分配。实际上没有内存或性能影响。当然,这并不是说这是最佳实践 - 这是一个不同的问题:)

@property(nonatomic, copy) NSString *MyProperty;
// ...
self.MyProperty = @"hi there";

This statement has a significant impact on memory and performance. This is essentially equivalent to:

此声明对内存和性能有重大影响。这基本上相当于:

-(void)setMyProperty(NSString *)newValue {
    if (MyProperty != newValue) {
        [MyProperty release];
        MyProperty = [newValue copy];
    }
}

The old value is released and the new value is copied into MyProperty. This is acceptable and especially typical when dealing with strings when the string your assigning is mutable (ie, it could change later).

旧值将被释放,新值将复制到MyProperty中。当你的赋值字符串是可变的(即,它可能在以后改变)时处理字符串时,这是可以接受的。

If, as in your example, you're simply assigning a static string (@"hi there"), there is nothing wrong with directly assigning the string value; it's more efficient however the difference in performance is trivial.

如果在你的例子中,你只是简单地指定一个静态字符串(@“hi there”),那么直接分配字符串值没有错;它的效率更高,但性能上的差异是微不足道的。

You can declare a property with @property as retain, copy, or assign (default is assign). You can then generate "accessor" (getter/setter) methods by using @synthesize. Here is what the setter methods look like that are generated when you do so:

您可以将@property的属性声明为retain,copy或assign(默认为assign)。然后,您可以使用@synthesize生成“访问器”(getter / setter)方法。以下是执行此操作时生成的setter方法的外观:

// @property(nonatomic, assign)
-(void)setMyProperty(NSString *)newValue {
    MyProperty = newValue;
}

// @property(nonatomic, retain)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue retain];
    }

// @property(nonatomic, copy)
-(void)setMyProperty(NSString *)newValue {
    if (property != newValue) {
        [property release];
        property = [newValue copy];
    }
}

More information on ObjectiveC Declared Properties.

有关ObjectiveC声明的属性的更多信息。

"You can use the @synthesize and @dynamic directives in @implementation blocks to trigger specific compiler actions. Note that neither is required for any given @property declaration.

“您可以在@implementation块中使用@synthesize和@dynamic指令来触发特定的编译器操作。请注意,任何给定的@property声明都不需要。

Important: If you do not specify either @synthesize or @dynamic for a particular property, you must provide a getter and setter (or just a getter in the case of a readonly property) method implementation for that property."

要点:如果没有为特定属性指定@synthesize或@dynamic,则必须为该属性提供getter和setter(或者只是readonly属性的getter)方法实现。“

In other words, if you declare a property but don't synthesize the property, you won't be able to use [self MyProperty] or self.MyProperty unless you define 'MyProperty' and 'setMyProperty' methods. If you don't declare a property then you simply have an instance variable.

换句话说,如果声明属性但不合成属性,除非定义“MyProperty”和“setMyProperty”方法,否则将无法使用[self MyProperty]或self.MyProperty。如果您没有声明属性,那么您只需要一个实例变量。

Note: @dynamic doesn't generate the accessors. It's really used if you're dynamically (ie, magically) resolving accessor methods via loading code or dynamic method resolution.

注意:@dynamic不会生成访问者。如果你通过加载代码或动态方法解析动态地(即,神奇地)解析访问器方法,它就真的被使用了。

#2


The difference is that

不同之处在于

self.MyProperty = @"hi there"

is dot-notation call that will call the generated accessor, which will handle the retain counts correctly (equivalent to [self setMyProperty:@"hi there"]), whereas

是点符号调用,它将调用生成的访问器,它将正确处理保留计数(相当于[self setMyProperty:@“hi there”]),而

MyProperty = @"hi there"

is a direct assignment to your member variable, which doesn't release the old value, retain the new one, or do anything else your accessor does (e.g., if you have a custom setter that does extra work).

是对您的成员变量的直接赋值,它不会释放旧值,保留新值或执行您的访问者所做的任何其他操作(例如,如果您有自定义setter执行额外工作)。

So yes, there is a big difference in memory management and in behavior in general between the two. The latter form is almost always wrong, unless you know specifically why you are doing it and that you are handling the retain counts correctly yourself.

所以,是的,内存管理和两者之间的行为存在很大差异。后一种形式几乎总是错误的,除非您明确知道为什么要这样做,并且您自己正确处理保留计数。

#3


If you use automatic Key-Value Observing (or any Cocoa technology that builds on it - like bindings, ...), it is also important use the setter. The observer would not receive any notification if you assign to the ivar. If you bind "MyProperty" to a NSTextfield and you change your "MyProperty" ivar via code, the bound textfield would still display the old value as it did not receive any change notification.

如果您使用自动键值观察(或基于它的任何Cocoa技术 - 如绑定,......),使用setter也很重要。如果您分配给ivar,观察员将不会收到任何通知。如果将“MyProperty”绑定到NSTextfield并通过代码更改“MyProperty”ivar,则绑定的文本字段仍会显示旧值,因为它没有收到任何更改通知。

#4


To access a variable, there is often no need to use the dot notation. Thus, in code generated by the XCode templates, you will see things like:

要访问变量,通常不需要使用点表示法。因此,在XCode模板生成的代码中,您将看到以下内容:

[flipsideViewController viewWillAppear:YES];

There is no need to write self.flipsideViewController here, because the accessor method typically does nothing except handing you the variable.

这里没有必要编写self.flipsideViewController,因为除了处理变量之外,访问器方法通常什么都不做。

So a good rule of thumb is to use dot notation when you are setting a variable (absolutely necessary unless you want to do your own retaining and releasing), but not when you're accessing it:

因此,一个好的经验法则是在设置变量时使用点符号(绝对必要,除非您想要自己保留和释放),但不是在您访问它时:

self.aString = @"Text text text";
NSLog (aString);   // No need for self.aString here
NSString* tmpString = aString; // Here neither

When you're using non-object types, like int or float or many others, you can get away with not using the dot notation/setter method. In these cases, there is nothing to retain, so the setter method will do little apart from just assigning the value.

当您使用非对象类型(如int或float或许多其他类型)时,您可以不使用点符号/ setter方法。在这些情况下,没有什么可以保留,因此setter方法除了分配值之外几乎没有什么作用。

However, synthesized getters and setters do more than just retaining and releasing. As others have mentioned, they are also the engine that keeps the KVO system running. Thus, you should use the proper setters even on ints, floats and the rest.

然而,合成的吸气剂和固定剂不仅仅是保留和释放。正如其他人所提到的,它们也是保持KVO系统运行的引擎。因此,即使在整数,浮点数和其余部分上也应该使用适当的设定器。

What about the accessors then? In more advanced contexts, a class might respond to a request for a variable's value even when the variable doesn't exist. To quote the exalted Objective-C manual, classes might provide "method implementations directly or at runtime using other mechanisms [than simple accessor methods] such as dynamic loading of code or dynamic method resolution."

那么访问者呢?在更高级的上下文中,即使变量不存在,类也可能响应对变量值的请求。为了引用高级的Objective-C手册,类可以直接或在运行时使用其他机制[而不是简单的访问器方法]提供“方法实现”,例如动态加载代码或动态方法解析。

(One way of implementing this sort of on-the-fly response to messages is by overriding NSObject methods like methodSignatureForSelector: and forwardInvocation: .)

(实现对消息的这种即时响应的一种方法是重写NSObject方法,如methodSignatureForSelector:和forwardInvocation:。)

For this reason, using properly declared interfaces (whether synthesized or not) is always a good idea when you're working on something big. But it's completely ok to access ivars directly, as long as you set them using the proper API.

出于这个原因,使用正确声明的接口(无论是否合成)总是一个好主意,当你在做大事。但只要您使用适当的API设置它们,就可以直接访问ivars。

(Note: I'm not a Cocoa guru, so corrections are more than welcome.)

(注意:我不是可可大师,因此非常欢迎更正。)

#5


For the second part of the question, property definition is not needed, it is a help to us . The @synthesize directive on property generates accessor methods for properties so we don't have to do it manually, and because:

对于问题的第二部分,不需要属性定义,这对我们有帮助。属性上的@synthesize指令为属性生成访问器方法,因此我们不必手动执行,因为:

This code instructs the compiler to generate, or synthesize, the accessor methods. The compiler will generate the accessor methods using well-tested, fast algorithms that are ready for multi-core and multi-threaded environments, including locking variables in setter methods. Not only does using properties reduce the amount of code that you have to write, it replaces that code with the best possible accessors for today's modern multi-core systems. Later, if you need to provide an alternative implementation for a property accessor, you can simply add the appropriate code to your class.

此代码指示编译器生成或合成访问器方法。编译器将使用经过充分测试的快速算法生成访问器方法,这些算法已准备好用于多核和多线程环境,包括在setter方法中锁定变量。使用属性不仅减少了您必须编写的代码量,而且还使用当今现代多核系统的最佳访问器替换了该代码。稍后,如果您需要为属性访问器提供替代实现,则只需将适当的代码添加到您的类中即可。

http://developer.apple.com/leopard/overview/objectivec2.html

The nonatomic will avoid use of locking when accessing variables, if you don't specify anything then default is atomic. Locking is useful on multithreaded systems. The copy specifies what code should be generated for accessors, copy will copy the object, retain will retain new object and release old one, assign is good for simple variables like int to just plain assign values. So when you define your property as you did above (nonatomic,copy) and then use self.MyProperty = @"Hey" you're actually calling generated accessor that will make a copy of the new variable as opposed to just assigning it. You can override accessor and add checking to it.

非原子会在访问变量时避免使用锁定,如果你没有指定任何东西,那么默认是原子的。锁定在多线程系统上很有用。副本指定应为访问器生成什么代码,copy将复制对象,retain将保留新对象并释放旧对象,赋值对于简单的变量(如int)只是简单赋值。因此,当你像上面那样定义你的属性(非原子,复制),然后使用self.MyProperty = @“嘿”你实际上调用生成的访问器,它将创建新变量的副本而不是仅仅分配它。您可以覆盖访问者并向其添加检查。

Because of the above I would say that defining property has benefits even when the variable is not used outside of the class.

由于上述原因,我会说定义属性即使在类之外没有使用变量也有好处。

I believe to access properties you should use self.MyProperty instead of just MyProperty but I can't point you to explanation why. Might be something to do with the fact that compiler will generate from

我相信访问属性你应该使用self.MyProperty而不仅仅是MyProperty,但我不能指出你解释原因。可能与编译器将生成的事实有关

self.MyProperty = @"Hey";

this:

[self setMyProperty: @"Hey"];

But I'm only speculating here.

但我只是在这里猜测。

Whether you call self.MyProperty or MyProperty it should not affect memory management (I would still prefer the first - self.MyProperty).

无论你是调用self.MyProperty还是MyProperty它都不应该影响内存管理(我还是更喜欢第一个 - self.MyProperty)。

See Objective-C 2.0 Overview for some high level description from Apple.

有关Apple的一些高级描述,请参阅Objective-C 2.0概述。

#6


As a supplement to the other answers, try to think of it this way:

作为其他答案的补充,尝试以这种方式思考:

self.MyProperty = @"hi there";

or

[self setMyProperty:@"hi there"];

(which are equivalent) both call a method, whereas

(相当于)都调用方法,而

MyProperty = @"hi there";

Simply sets a variable.

只需设置变量即可。

#7


This is an old question, though it used to be "When do I write [self setMyProperty:@"hi there"]?" (Note that self.MyProperty = @"hi there" is exactly equivalent to this.)

这是一个老问题,虽然它曾经是“我什么时候写[self setMyProperty:@”hi there“]?” (注意self.MyProperty = @“hi there”与此完全相同。)

The answer I've always heard (and which makes good sense) is always use the accessor; never write MyProperty = @"hi there". There are several reasons:

我一直听到的答案(而且很有道理)总是使用访问器;永远不要写MyProperty = @“hi there”。有几个原因:

  1. Memory management is handled for you; you don't have to worry about proper retaining/releasing/copying.
  2. 内存管理是为您处理的;你不必担心正确的保留/释放/复制。

  3. It's easier to modify your code in the future; if at some point you realize that changing MyProperty needs to have a particular side effect, you can add to the setter method without finding every time you set MyProperty.
  4. 将来修改代码会更容易;如果在某些时候您意识到更改MyProperty需要具有特定的副作用,您可以添加到setter方法而不会在每次设置MyProperty时找到。

  5. If you ever have problems with MyProperty, it's easy to add logging code to the setter (or even getter) to find out every time it's changed (or even accessed).
  6. 如果您遇到MyProperty问题,可以轻松地将记录代码添加到setter(甚至是getter),以便在每次更改(甚至访问)时找到它们。

Summary: it's safest and most flexible to always use [self setMyProperty:@"hi there"] or self.MyProperty = @"hi there", and never use MyProperty = @"hi there".

总结:总是使用[self setMyProperty:@“hi there”]或self.MyProperty = @“hi there”是最安全和最灵活的,并且从不使用MyProperty = @“hi there”。

#8


Still not clear on when to use the accessors and when to do direct assignment on ivars ? I have seen lot of Apple examples which directly access the ivars. So using properties for all ivars seems pedantic overkill.

还不清楚何时使用访问器以及何时在ivars上进行直接分配?我见过许多直接访问ivars的Apple示例。所以使用所有ivars的属性似乎是迂腐的矫枉过正。

It seems only significant ivars which need to be around longer and are accessed outside tend to use the properties.

似乎只有重要的ivars需要更长时间并且在外部访问倾向于使用属性。

Would appreciate some Cocoa gurus to step in and clarify.

希望一些可可大师介入并澄清。