Avoiding #property-itis (i.e. overuse of properties, when are they appropriate)? - objective-c

Objective-C 2.0 gave us #properties.
They allow for introspection.
They allow for declarative programming.
The #synthesize and #dynamic mechanisms relieve use from having to write repetitive, stock accessors.
Finally, there is the ‘dot’ property syntax, which some love, and some hate.
That isn't what I'm hear to ask. Like any new feature, there is an initially tendency to want to use #property everywhere. So where is property use appropriate?
Clearly in model objects, attributes and relationships are good fodder for properties.
#property(...) NSString *firstName;
#property(...) NSString *lastName;
#property(...) Person *parent;
Even synthesized/computed attributes seem like a good use case for properties.
#property(...) NSString *fullName;
Where else have you used properties? Where have you used them, then later decided it was an inappropriate use of the feature?
Do you use properties for your private object attributes?
Can you think of any examples of things which aren't properties in Cocoa, which at first look, seem like they might want to be properties, but after closer inspection, are actual an example of abuse or property-itis?

My recommendation to people is to use property's wherever possible. If you are working in a framework, the ability to use non-fragile instance variables in the modern runtime is a huge bonus and if you aren't, properties make it clear how your ivars are to be managed (assigned vs retained vs copied). There isn't an inherent performance loss from declaring a property other than the time it takes to write the line of code (I actually use a TextExpander snippet to do this for me) but the potential for preventing bugs is large enough that it becomes a fantastic best-practice. If you do plan to user properties for private ivars, you can do so inside your implementation file via an #interface block. For example
#interface MyObject()
#property(retain) NSArray *myArray;
#end

If I had to think of a reason to avoid them, I'd say don't use it for computed attributes where the computation involved is significant. Properties encourage code like:
if (foobar.weight > 100) {
goober.capacity = foobar.weight;
}
In this example, foobar.weight is called twice. If it's just returning a cached value, no problem. But if it needs to block the thread while it deploys a robot to manually weigh the foobar each time, the above snipped of code would waste two robot deployments when only one is needed.
In such cases, I'd recommend NOT using a property, and also naming the method differently, so that the code would look more like:
int w = [foobar computeWeight];
if (w > 100) {
goober.capacity = w;
}
With a name like computeWeight it is easier to remember that it is a long running operation.

I would avoid using properties if the accessor method does something non-obvious to the object, like setting an unrelated instance variable. Also if the property being returned doesn't really "belong" to the object. For instance, in one of my projects I have a stringValue method that I decided not to make a property for this reason. This is really more a matter of style though.

Related

Difference between self.name and _name using modern Objective-C

Say this is in my header file:
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (weak) IBOutlet NSSlider *slider;
- (void)doSomething;
#end
…and this is the *m:
#implementation AppDelegate
- (void) doSomething {[self.slider setFloatValue:0];}
#end
I'm new to Xcode and Objective C, and I would like to use and understand the modern “tools” presented by Apple in its documentation, namely ARC, or here more specifically the ability to skip #synthesize.
If I understood correctly, #property (weak) IBOutlet NSSlider *slider; does a few things for me, including:
creating an instance variable called _slider;
creating a getter named slider;
creating a setter named setSlider.
I've been doing C++ until now, so I see instance variables as the equivalent of what I am calling (rightly, I hope) members of my C++ classes, which I incidentally always call _member.
I understand that the whole point of encapsulation is that, if you're outside a given class, you have to use accessors to access those variables; they are private to you, so there's no way you can access them via _member even if you tried.
But, when I'm writing my *.m file of my class, _member means something. Back to my example, I think self.slider and _slider are equivalent. The latter comes naturally to mind first, as it saves a few character.
My question is: are the two absolutely equivalent?
I know this looks similar to this question, for example, but here’s a few reasons why I wanted to ask myself:
I don’t use #synthesize, so I’m really not the one creating _slider, and I wonder if this makes a difference (I believe this is a fairly recent improvement of ObjC, and most answers still refer to #synthesize);
it seems that on average, most conversations end up with “so, just use self.name”, but I don’t grasp if this is just a recommendation, a convention, of something more important (with an impact on, say, the performance);
similarly, some say you should only use _name in methods like dealloc and its friends; but I don’t write those thanks to ARC, so does this mean I should never use _name? If so, why?
I hope this justifies this post, I apologies if I missed a preexisting answer. Thanks in advance for your help.
self.name = compiles to [self setName:] this is very different then setting the variable directly.
One of the main reasons that using the default setter differs deals with key value observing often referred to as KVO. Using the setter will notify observers of changes, setting the _name directly will not.
Thats not to say you can't fire the events your self with willChangeValueForKey: and didChangeValueForKey:, but the default implementation will handle that for you. So as you say outside the class accessing them you have to use the property get/set but inside your class setting the variable directly will lose out on some notifications. I'm sure there are other differences this is the first that comes to mind.
Using the variable directly does have it's use cases, such as a custom property setter. I think the main take away is the dot syntax is a hidden function call to get/set.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html
Under basic circumstances, where you use the pre-made accessors, you could probably get away with using _slider or self.slider within your class interchangeably. They're not equivalent in how they compile necessarily, but the functionality could be said to be equivalent.
The bigger issue comes into play when you start overriding those accessors. When those accessors do more than just "getting" or "setting" a variable, such as accessing some sort dependency variable, accessing the instance variable directly bypasses that functionality that the accessors provide. In these cases, I don't think it can be said that the two are equivalent at all.

When to use properties vs. plain ol' getters and setters

I'm just wondering about semantics. When is something truly a "property" of an object? I noticed in a lot of Apple's APIs, they explicitly define getters and setters instead of using properties (e.g. URL and setURL on NSURLRequest/NSMutableURLRequest; surely the URL seems like a "property" of an URL request, right?) I'm wondering if there's some subtle thing that I'm missing or if Apple just doesn't like properties all that much. =P
UPDATE: As of iOS 8, Apple has converted most (if not all) of their non-property getters and setters to properties. (Probably done so that Swift compatibility would be easier.)
or if Apple just doesn't like properties all that much.
The real cause is that most of the Foundation framework (let's not forget you're talking about NS* classes) is old as dirt - they have been around there since the NeXT times... At that time, the Objective-C language didn't sport the #property keyword - to emulate properties, it was necessary for the programmers to declare and implement getter and setter methods manually, this applied to Apple's code as well.
Now the Foundation framework is so fundamental that it hasn't changed a lot. It hasn't been radically rewritten and as far as I'm concerned, programmers who wrote it didn't bother rewriting all the code using the new syntax. You can see that recently added classes do in fact feature declared properties instead of getters and setters, but that's not true for older classes.
Anyway, properties declared manually and those declared using #property and #synthesize are completely equivalent. That said, there's a very minor difference when accessing them, but that doesn't belong to the declaration thingy: if you write
someObject.someProperty
in your code, the someObject must have a complete and concrete type, so if a property named someProperty is nonexistent, you'll get a compiler error. In contrast,
[someObject someProperty]
and
[someObject setSomeProperty:]
allow you the method call even if it's undeclared.
Edit:
I ask what the semantic difference between them is
So by "semantic difference", you meant "when it should be used" rather than "does it run differently". I see. Well... Conceptually, properties represent state. A property is a particular characteristic of an object that may change over time. It's just an unrelated fact that properties are accessed using accessor methods in Objecive-C.
If you write a method that acts on the obejct (other than setting a property, of course), there's a fair chance you should be declaring and calling it as a method. If you access (read or write) an attribute of an object, that better fits the task of a property.
Having a getter and setter lets you use messages to access the item
[myObject someProperty] or [myObject setSomeProperty: someNewValue]
Making something a #property gives you the additionally ability to use dot notation to call the getter and setter. This is because #property chooses method names that make the class key-value-coding compliant for the particular value.
myObject.someProperty or myObject.someProperty = someNewValue
While it is possible to do this manually, it is considered best-practice to use #property when you want to use the dot notation. Over time, the behind-the-scenes bahaviours of #property and #synthesize have changed quite a bit particularly in regard to auto-creating storage for the associated pointer. Using #property makes it easier to keep up with Apple's changes in convention with little or no change in your code.
Additionaly, using #property makes your code much easier to read.

Must every ivar be a property?

I see it recommended all over the place when coding for iOS that properties should be used for accessing instance variables because of the benefits this lends to memory management, among other things.
This advice doesn't sit terribly well with me. I find that using properties instead of plain old ivars just takes too much code and I don't really see the benefits if you're comfortable with memory management. Is it really that important? What's your approach to managing instance variables?
It's not really necessary to declare properties for all ivars. A few points come to mind:
If an ivar is only going to be assigned to once during the lifetime of the object, you don't really gain anything by declaring a property. Just retain/copy/assign during init and then release as necessary during dealloc.
If an ivar is going to be changed frequently, declaring a property and always using the accessors will make it easier to avoid memory management errors.
You can declare properties in a class extension in the .m file rather than the .h file if the properties and ivars are meant to be private.
When targeting iOS 4.0+, you don't need to declare ivars at all in your header if you define a property and synthesize accessors.
So I generally use properties, but for things like a NSMutableArray that an object allocates during init and uses to hold a bunch of whatevers, I'll use a plain old ivar since I'll never be reassigning the ivar.
While Daniel's answer is correct, I think it misses an important point. Namely:
I find that using properties instead
of plain old ivars just takes too much
code and I don't really see the
benefits if you're comfortable with
memory management.
The benefits are consistency; consistent memory management and consistent behavior.
Notably, these two lines of code can actually have extremely different behavior at runtime:
iVar = [foo retain];
self.iVar = foo;
The first is a direct setting of the instance variable and there will be no change notifications. The second goes through the setter and, thus, preserves any subclass customizations upon set and ensures that any observers of the property are notified of the change.
If you are using ivars directly throughout your code (internally to the class -- if you are using ivars of an instance directly from outside that instance, well... any contractor working on your codebase should double their rates ;), then you must either also handle change notification propagation manually (typically by calling willChangeValueForKey:/didChangeValueForKey) or explicitly engineer your application to avoid use of mechanisms that rely upon Key-Value Observation.
You say "takes too much code". I don't see that; in the above two lines of code, the dot syntax is fewer characters. Even calling the setter method using traditional syntax would be less code.
And do not discount the value in centralizing memory management; one accidental omission in a myriad of call sites and crash city.
Property are just syntax sugar that avoid you to write same methods over and over.
With a property you have a setter that release the old object and retain the new one for free.
For the private fields - I suggest it is safe to use direct ivars only for primitive types (BOOL/int/float etc). I find a good practice wrapping everything related to memory-management in properties - even rarely-used fields. Additional bonus of this approach is that IDE usually highlights direct ivars access differently, so you always have a nice separation of simple scalar fields and object-type fields.
Contrary to this I would strongly discourage any direct ivars in the class public interface. Because of the dynamic nature of language it can lead to runtime errors that are extremely hard to find, localize and fix. Consider the following hierarchy
#interface BaseControl
...
#end
#interface Label : BaseControl
...
#end
#interface Button : BaseControl {
#public
BOOL enabled;
}
#end
and a code snippet
- (void)enableAllButtons {
NSArray *buttons = [self getAllButtons]; // expected to contain only Button instances
for (Button *button in buttons) {
button->enabled = YES;
}
}
Now imagine there's an error somewhere in -getAllButtons logic and you also get some Label's returned in that array - so those Label class instances will get missing ivar assigned. The fact that may be surprising is that -enableAllButtons will not crash in that case. But at that point those Label instances internal structure is corrupted and this will cause undefined behavior and crashes when they are used elsewhere.
Like some popular problems with memory management (and in general - with dangling pointers) - this kind of problems is hard to find and localize - because the appearance of the error usually is distant (in terms of time, code or app flow) from the place, causing the error. But with that particular problem you even don't have handy tools (like leak/zombies analyzers etc.) to help you localize and fix it - even when you learn how to reproduce it and can easily investigate erroneous state.
Obviously if you use #property (assign) BOOL enabled; you'll get an easy-to diagnose and fix runtime exception in -enableAllButtons.

Should I use properties or direct reference when accessing instance variables internally?

Say I have a class like this:
#interface MyAwesomeClass : NSObject
{
#private
NSString *thing1;
NSString *thing2;
}
#property (retain) NSString *thing1;
#property (retain) NSString *thing2;
#end
#implementation MyAwesomeClass
#synthesize thing1, thing1;
#end
When accessing thing1 and thing2 internally (i.e, within the implementation of MyAwesomeClass), is it better to use the property, or just reference the instance variable directly (assuming cases in which we do not do any work in a "custom" access or mutator, i.e., we just set and get the variable). Pre-Objective C 2.0, we usually just access the ivars directly, but what's the usual coding style/best practice now? And does this recommendation change if an instance variable/property is private and not accessible outside of the class at all? Should you create a property for every ivar, even if they're private, or only for public-facing data? What if my app doesn't use key-value coding features (since KVC only fires for property access)?
I'm interested in looking beyond the low-level technical details. For example, given (sub-optimal) code like:
#interface MyAwesomeClass : NSObject
{
id myObj;
}
#proprety id myObj;
#end
#implementation MyAwesomeClass
#synthesize myObj;
#end
I know that myObj = anotherObject is functionally the same as self.myObj = anotherObj.
But properties aren't merely fancy syntax for instructing the compiler to write accessors and mutators for you, of course; they're also a way to better encapsulate data, i.e., you can change the internal implementation of the class without rewriting classes that rely on those properties. I'm interested in answers that address the importance of this encapsulation issue when dealing with the class's own internal code. Furthermore, properly-written properties can fire KVC notifications, but direct ivar access won't; does this matter if my app isn't utilizing KVC features now, just in case it might in the future?
If you spend time on the cocoa-dev mailing list, you'll find that this is a very contentious topic.
Some people think ivars should only ever be used internally and that properties should never (or rarely) be used except externally. There are various concerns with KVO notifications and accessor side effects.
Some people think that you should always (or mostly) use properties instead of ivars. The main advantage here is that your memory management is well contained inside of accessor methods instead of strewn across your implementation logic. The KVO notifications and accessor side effects can be overcome by creating separate properties that point to the same ivar.
Looking at Apple's sample code will reveal that they are all over the place on this topic. Some samples use properties internally, some use ivars.
I would say, in general, that this is a matter of taste and that there is no right way to do it. I myself use a mix of both styles.
I don't think any way is 'better'. You see both styles in common use, so there isn't even a usual/best practice now. In my experience, the style used has very little impact on how well I digest some implementation file I am looking. You certainly want to be comfortable with both styles (and any in between) when looking at other people's code.
Using a property for every internal ivar might be going slightly overboard, in terms of maintenance. I've done it, and it added a non-trivial amount of work that I don't think paid off for me. But if you have a strong desire/OCD for seeing consistent code like self.var everywhere, and you have it in the back of your mind every time you look at a class, then use it. Don't discount the effect that a nagging feeling can have on productivity.
Exceptions- Obviously, for custom getters (e.g. lazy creation), you don't have much of a choice. Also, I do create and use a property for internal setters when it makes it more convenient (e.g. setting objects with ownership semantics).
"just in case", "might" is not be a compelling reason to do something without more data, since the time required to implement it is non-zero. A better question might be, what is the probability that all the private ivars in some class will require KVC notifications in the future, but not now? For most of my own classes, the answer is exceedingly low, so I now avoid a hard rule about creating properties for every private ivar.
I've found that when dealing with internal implementations, I quickly get a good handle on how each ivar should be accessed regardless.
If you are interested, my own approach is this:
Reading ivars: Direct access, unless there is a custom getter (e.g. lazy creation)
Writing ivars: Directly in alloc/dealloc. Elsewhere, through a private property if one exists.
The only difference in an assignment of thing1 = something; and self.thing1 = something; is that if you want to have the property assignment operation (retain, copy, etc), done on the assigned object, then you need to use a property. Assigning without properties will effectively be just that, assigning a reference to the provided object.
I think that defining a property for internal data is unnecessary. Only define properties for ivars that will be accessed often and need specific mutator behavior.
If thing1 is used with KVO it is a good idea to use self.thing1= when you set it. If thing1 is #public, then it is best to assume that someone someday will sometime want to use it with KVO.
If thing1 has complex set semantics that you don't want to repeat everywhere you set it (for example retain, or non-nonatomic) then use through self.thing1= is a good idea.
If benchmarking shows that calling setThing1: is taking significant time then you might want to think about ways to set it without use of self.thing1= -- maybe note that it can not be KVO'ed, or see if manually implementing KVO is better (for example if you set it 3000 times in a loop somewhere, you might be able to set it via self->thing1 3000 times, and make 2 KVO calls about the value being about to change and having changed).
That leaves the case of a trivial setter on a private variable where you know you aren't using KVO. At that point it stops being a technical issue, and falls under code style. At least as long as the accessor doesn't show up as a bottleneck in the profiler. I tend to use direct ivar access at that point (unless I think I will KVO that value in the future, or might want to make it public and thus think others may want to KVO it).
However when I set things with direct ivar access I try to only do it via self->thing1=, that makes it a lot simpler to find them all and change them if I ever find the need to use KVO, or to make it public, or to make a more complex accessor.
Other things mentioned here are all right on. A few things that the other answers missed are:
First, always keep in mind the implications of accessors/mutators being virtual (as all Objective-C methods are.) In general, it's been said that one should avoid calling virtual methods in init and dealloc, because you don't know what a subclass will do that could mess you up. For this reason, I generally try to access the iVars directly in init and dealloc, and access them through the accessor/mutators everywhere else. On the other hand, if you don't consistently use the accessors in all other places, subclasses that override them may be impacted.
Relatedly, atomicity guarantees of properties (i.e. your #properties are declared atomic) can't be maintained for anyone if you're accessing the iVar directly anywhere outside of init & dealloc. If you needed something to be atomic, don't throw away the atomicity by accessing the iVar directly. Similarly, if you don't need those guarantees, declare your property nonatomic (for performance.)
This also relates to the KVO issue. In init, no one can possibly be observing you yet (legitimately), and in dealloc, any remaining observer has a stale unretained (i.e. bogus) reference. The same reasoning also applies to the atomicity guarantees of properties. (i.e. how would concurrent accesses happen before init returns and accesses that happen during dealloc are inherently errors.)
If you mix and match direct and accessor/mutator use, you risk running afoul of not only KVO and atomicity, but of subclassers as well.

Performance difference between dot notation versus method call in Objective-C

You can use a standard dot notation or a method call in Objective-C to access a property of an object in Objective-C.
myObject.property = YES;
or
[myObject setProperty:YES];
Is there a difference in performance (in terms of accessing the property)? Is it just a matter of preference in terms of coding style?
Dot notation for property access in Objective-C is a message send, just as bracket notation. That is, given this:
#interface Foo : NSObject
#property BOOL bar;
#end
Foo *foo = [[Foo alloc] init];
foo.bar = YES;
[foo setBar:YES];
The last two lines will compile exactly the same. The only thing that changes this is if a property has a getter and/or setter attribute specified; however, all it does is change what message gets sent, not whether a message is sent:
#interface MyView : NSView
#property(getter=isEmpty) BOOL empty;
#end
if ([someView isEmpty]) { /* ... */ }
if (someView.empty) { /* ... */ }
Both of the last two lines will compile identically.
Check out article from Cocoa is My Girlfriend. The gist of it, is that there is no performance penalty of using one over the other.
However, the notation does make it more difficult to see what is happening with your variables and what your variables are.
The only time you'll see a performance difference is if you do not mark a property as "nonatomic". Then #synthesize will automatically add synchronization code around the setting of your property, keeping it thread safe - but slower to set and access.
Thus mostly you probably want to define a property like:
#property (nonatomic, retain) NSString *myProp;
Personally I find the dot notation generally useful from the standpoint of you not having to think about writing correct setter methods, which is not completely trivial even for nonatomic setters because you must also remember to release the old value properly. Using template code helps but you can always make mistakes and it's generally repetitious code that clutters up classes.
A pattern to be aware of: if you define the setter yourself (instead of letting #synthesize create it) and start having other side effects of setting a value you should probably make the setter a normal method instead of calling using the property notation.
Semantically using properties appears to be direct access to the actual value to the caller and anything that varies from that should thus be done via sending a message, not accessing a property (even though they are really both sending messages).
As far as I've seen, there isn't a significant performance difference between the two. I'm reasonably certain that in most cases it will be 'compiled' down to the same code.
If you're not sure, try writing a test application that does each method a million times or so, all the while timing how long it takes. That's the only way to be certain (although it may vary on different architecture.)
Also read this blog post on Cocoa with Love:
http://cocoawithlove.com/2008/06/speed-test-nsmanagedobject-objc-20.html
There the author compares the speed of custom accessor and dot notations for NSManagedObject, and finds no difference. However, KVC access (setValue:forKey:) appears to be about twice as slow.