Is it just because the second method with the setter can be called outside of its own class?
Well, that depends on how your instance variable is declared. By default, instance variables are @protected, i. e. they can be accessed from within the class and its subclasses only. However, if you explicitly declare an ivar as @public, then you can access it outside the class, using the C struct pointer member operator ->:
obj->publicIvar = 42;
However, this is not recommended, since it violates encapsulation.
Furthermore, if you use a custom setter method, then you have the opportunity to do custom actions when a property of an instance is updated. For example, if one changes the backgroundColor property of a UIView, it needs to redraw itself in addition to assigning the new UIColor object to its appropriate ivar, and for that, a custom setter implementation with side effects is needed.
Additionally, there are retained ("strong") and copied properties in case of instance variables that hold object. While writing a setter for a primitive type such as an integer is as simple as
- (void)setFoo:(int)newFoo
{
_foo = newFoo;
}
then, in contrast, a retained or copied property needs proper memory nanagement calls:
- (void)setBar:(Bar *)newBar
{
if (_bar != newBar) {
[_bar release];
_bar = [newBar retain]; // or copy
}
}
Without such an implementation, no reference counting would take place, so the assigned object could either be prematurely deallocated or leaked.