Q:

When to use self on class properties?

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?
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?

A:

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).
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.
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(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.
"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.
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."
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.
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.

A:

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
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).
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.

A:

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.

