Objective-C class without properties? - objective-c

I'm in the process of looking over some code in a large project, and I have noticed that in several of the classes, instance variables are created but no corresponding properties (#property) are created.
Is it "wrong" to create instance variables without properties? Doesn't this become a memory management issue?
I've actually never seen code like this before so I'm not sure what to think at this point.
Thanks in advance!

#properties are merely shorthand -- very convenient short-hand -- for code you can write yourself, no magic about it.
It may also be that the #properties are declared in the implementation file within a class extension and there is no publicly accessible API for directly manipulating the instance variables.

There's no reason that you have to use the Objective-C 2 style setters/getters to manage your instance variables - as long as the instance variable is released within the dealloc method (if indeed it's a alloced/inited object, etc.) then there's nothing to worry about.
Bear in mind that prior to Objective-C, such properties (and the whole #property/#synthesize syntax) simply didn't exist, so you had to create your own getters/setters if you deemed it necessary/convenient.

Not at all. Instance variables work fine, and are subject to the same memory management rules as anything else: retain it before saving it to the instance var, and make sure you release it when you don't need it anymore (typically in the dealloc).
Some history here might be helpful:
In the beginning, there were only instance variables. "Properties" existed only in an informal way, by convention, for objects outside your class to access "public" data that the class exposed. You'd write your own -(Foo *)foo and -(void)setFoo:(Foo *)f methods for each of these. Those often were like boilerplate code, trivially returning the ivar in the first case, and doing the right retain/release/set dance in the latter.
So Objective-C 2.0 came along and gave us the ability to declare properties with the language syntax, and even generate the accessors for us-- lots of time and boilerplate code was saved.
As time went on, some people began to think about all ivars as "properties", public or private. The public ones appear in the .h file as #properties, but you can also create a private interface to your object in the .m file that declare your "private" #properties, so you can use the accessors inside your class. This might or might not be overkill, depending on your philosophy to it, but this I think has to the situation you see now, where naked ivars look suspicious.
They shouldn't. Instance variables happily exist without any of the other machinery. Just get your retain/release right (in non-GC runtimes).
As you get more advanced, see #bbum's answer to this question:
Must every ivar be a property?
for some more varsity things to think about around the benefits of properties around KVO and subclassing.

Properties for instance variables aren't mandatory. In fact, prior to v2.0 of Objective-C, there was no such thing as properties -- you had to write your own accessors and mutators for instance variables (if you wanted to access them outside of the class). Properties can simplify memory management, but to be honest, memory management of ivars isn't that difficult, and it's not hard to handle yourself.

Related

Case for not using Properties in Objective-C

In the apple OS X 10.8 Core Library Documentation under Programming with Objective-C, it states,
"It's best practice to use a property on an object any time you need to
keep track of a value or another object. If you do need to define
your own instance variables without declaring a property, you can add
them inside braces at the top of the class interface or
implementation..."
So I'm curious, then, what are going to be the cases where you need to define instance variables without declaring properties? Aside from what apple says, could it really just be a personal preference thing?
Thanks!
Some of it is definitely a matter of preference, but not everything: you are better off with a property for items with external visibility, and items that need different access control inside vs. outside your class. The issue has been much less pronounced since the introduction of ARC, because before it you may wanted to use properties for automated calls of retain and release. The significance of this aspect of properties has been reduced greatly to situations when you need to automatically copy the objects into your property.
If you're using ARC and a recent runtime (recent enough to let you declare your ivars in your #implementation block), then instance variables are suddenly awesome again. Why? Because unlike #properties they're class-specific. No risk they'll accidentally be overridden by a subclass.
They're also faster in the simple case, since you don't call any methods to get or set them.
I personally also find it much cleaner. No more class extensions defining private #properties, and all that junk. Just ivars, nice and simple.
So the best advice, IMHO, is to use them by default. Only use #properties if you actually need their functionality, e.g.:
You need a way to access them from outside your class.
You want to allow subclasses to override them.
Your getter or setter is more than just a trivial assignment.
The latter two are all actually rarer than you might think. It's generally unwise to try to override properties in subclasses, just because it's a little unusual and there are some rough edges.
If you do find, later, that you need to upgrade an ivar to a #property, it's nice and easy - the only place it can be accessed is in your #implementation, so it's generally a simple search-and-replace to add "self." to its references (and maybe remove the leading underscore, if you name them that way). 'til then you needn't pay the cost and run the risks of using #properties.
I prefer properties because I am able to define setters/getters and because I like more that syntax.
Many people affirm that is a bad practice to use ivars, like in this article:
http://cocoasamurai.blogspot.it/2012/08/cover-up-those-ivars.html
Unfortunately nowadays programmers call bad practice all what they don't like, even without objective reasons.
If you declare an ivar you still can use the #private directive, so isn't a matter of exposing or not variables.I think that if you like more ivars you should use them.

When to use instance variables and when to use properties

When using Objective-C properties can you stop creating instance variables altogether or do explicit instance variables (not the ones synthesized by the properties) still serve a purpose where properties would be inappropriate?
can you stop creating instance variables altogether
No, you can't (in a sense). What you can do is stop declaring them if you have properties. If you synthesize a property and you haven't declared the instvar, it will get declared for you, so you are creating an instance variable, just not explicitly.
do they still serve a purpose where properties would be inappropriate?
It used to be the advice to create properties for everything because having synthesized properties does almost all of the retains and releases for you. However, with ARC that reason for using properties to wrap the memory management has gone away. The advice now (for ARC) is, I believe, use properties to declare your external interface, but use direct instance variables where the variable is part of the object's internal state.
That's a good reason to adopt ARC: properties revert to their true purpose only of being part of the class's API and it's no longer necessary to use them as a hacky way to hide memory management work.
Edit
One more thing: you can now declare instance variables in the #implementation so there is now no need to leak any implementation details in the #interface. i.e.
#implementation MyClass
{
NSString* myString;
}
// method definitions
#end
And I'm pretty sure it works in categories too. - see comment below
I recommend declaring everything as properties and avoiding manual ivars altogether. There is no real upside to manually creating ivars. Declare public properties in your header #interface, declare private properties in a private class extension in your .m file.
To some of JeremyP's points, internal use of accessors still has significant value under ARC, even though memory management is no longer a significant concern. It ensures that KVO works properly, subclasses better, supports custom setters (particularly for things like NSTimer), supports custom getters (such as for lazy instantiation), etc. It is exceedingly error-prone to have a mix of accessors and ivars. It's far too easy to forget which you need to access in which way. Consistency is the hallmark of good ObjC.
If you absolutely must declare an ivar for some reason, then you should do it in the #implementation block as JeremyP notes.
UPDATE (Oct-2013):
Apple's guidance (From Programming with Objective-C: Encapsulating Data):
Most Properties Are Backed by Instance Variables
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self:
...
The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.
This question was addressed before here
When you use synthesize the instance variables are handled and instantiated for you. If you're using Lion with the new version of XCode also take a look at the various properties in ARC in Transitioning to ARC
you can always access properties from outside. So if you want a variable only to be read from inside a class you still have to declare a iVar. Also accessing a public ivar with object->ivar is slightly faster than using a method-call.

In Objective-C, if #property and #synthesize will add getter and setter, why not just make an instance variable public?

In Objective-C, we can add #property and #synthesize to create a property -- like an instance variable with getter and setter which are public to the users of this class.
In this case, isn't it just the same as declaring an instance variable and making it public? Then there won't be the overhead of calling the getter and setter as methods. There might be a chance that we might put in validation for the setter, such as limiting a number to be between 0 and 100, but other than that, won't a public instance variable just achieve the same thing, and faster?
Even if you're only using the accessors generated by #synthesize, they get you several benefits:
Memory management: generated setters retain the new value for a (retain) property. If you try to access an object ivar directly from outside the class, you don't know whether the class might retain it. (This is less of an issue under ARC, but still important.)
Threadsafe access: generated accessors are atomic by default, so you don't have to worry about race conditions accessing the property from multiple threads.
Key-Value Coding & Observation: KVC provides convenient access to your properties in various scenarios. You can use KVC when setting up predicates (say, for filtering a collection of your objects), or use key paths for getting at properties in collections (say, a dictionary containing objects of your class). KVO lets other parts of your program automatically respond to changes in a property's value -- this is used a lot with Cocoa Bindings on the Mac, where you can have a control bound to the value of a property, and also used in Core Data on both platforms.
In addition to all this, properties provide encapsulation. Other objects (clients) using an instance of your class don't have to know whether you're using the generated accessors -- you can create your own accessors that do other useful stuff without client code needing changes. At some point, you may decide your class needs to react to an externally made change to one of its ivars: if you're using accessors already, you only need to change them, rather than make your clients start using them. Or Apple can improve the generated accessors with better performance or new features in a future OS version, and neither the rest of your class' code nor its clients need changes.
Overhead Is Not a Real Issue
To answer your last question, yes there will be overhead—but the overhead of pushing one more frame and popping it off the stack is negligible, especially considering the power of modern processors. If you are that concerned with performance you should profile your application and decide where actual problems are—I guarantee you you'll find better places to optimize than removing a few accessors.
It's Good Design
Encapsulating your private members and protecting them with accessors and mutators is simply a fundamental principle of good software design: it makes your software easier to maintain, debug, and extend. You might ask the same question about any other language: for example why not just make all fields public in your Java classes? (except for a language like Ruby, I suppose, which make it impossible to expose instance variables). The bottom line is that certain software design practices are in place because as your software grows larger and larger, you will be saving yourself from a veritable hell.
Lazy Loading
Validation in setters is one possibility, but there's more you can do than that. You can override your getters to implement lazy loading. For example, say you have a class that has to load some fields from a file or database. Traditionally this is done at initialization. However, it might be possible that not all fields will actually be used by whoever is instantiating the object, so instead you wait to initialize those members until it's requested via the getter. This cleans up initialization and can be a more efficient use of processing time.
Helps Avoid Retain Cycles in ARC
Finally, properties make it easier to avoid retain loops with blocks under ARC. The problem with ivars is that when you access them, you are implicitly referencing self. So, when you say:
_foo = 7;
what you're really saying is
self->_foo = 7;
So say you have the following:
[self doSomethingWithABlock:^{
_foo = 7;
}];
You've now got yourself a retain cycle. What you need is a weak pointer.
__block __weak id weakSelf = self;
[self doSomethingWithABlock:^{
weakSelf->_foo = 7;
}];
Now, obviously this is still a problem with setters and getters, however you are less likely to forget to use weakSelf since you have to explicity call self.property, whereas ivars are referenced by self implicitly. The static analayzer will help you pick this problem up if you're using properties.
#property is a published fact. It tells other classes that they can get, and maybe set, a property of the class. Properties are not variables, they are literally what the word says. For example, count is a property of an NSArray. Is it necessarily an instance variable? No. And there's no reason why you should care whether it is.
#synthesize creates a default getter, setter and instance variable unless you've defined any of those things yourself. It's an implementation specific. It's how your class chooses to satisfy its contractual obligation to provide the property. It's just one way of providing a property, and you can change your implementation at any time without telling anyone else about it.
So why not expose instance variables instead of providing getters and setters? Because that binds your hands on the implementation of the class. It makes other acts rely on the specific way it has been coded rather than merely the interface you've chosen to publish for it. That quickly creates fragile and inter-dependent code that will break. It's anathema to object-oriented programming.
Because one would normally be interested in encapsulation and hiding data and implementations. It is easier to maintain; You have to change one implementation, rather than all. Implementation details are hidden from the client. Also, the client shouldn't have to think about whether the class is a derived class.
You are correct... for a few very limited cases. Properties are horrible in terms of CPU cycle performance when they are used in the inner loops of pixel, image and real-time audio DSP (etc.) code. For less frequent uses, they bring a lot of benefits in terms of readable maintainable reusable code.
#property and #synthesize is set are getting getter and setter methods
other usage is you can use the that variable in other classes also
if you want to use the variable as instance variable and your custom getter and setter methods you can do but some times when you set the value for variable and while retrieving value of variable sometimes will become zombie which may cause crash of your app.
so the property will tell operating system not to release object till you deallocate your object of class,
hope it helps

With ARC why use #properties anymore?

In non-ARC code retained properties handily take care of memory management for you using the self.property = syntax, so we were taught to use them for practically everything.
But now with ARC this memory management is no longer an issue, so does the reason for using properties evaporate? is there still any good reason (obviously other than providing public access to instance variables) to use properties anymore?
But now with ARC this memory management is no longer an issue, so does
the reason for using properties evaporate? is there still any good
reason (obviously other than providing public access to instance
variables) to use properties anymore?
Yes -- by using #property and #synthesized getters/setters, you guarantee that:
your getter/setter can be subclassed and subclasses can override storage and/or behavior
everything remains nicely encapsulated
you can use observation hooks -- KVO, etc... -- to monitor changes internally and externally
you have a convenient spot to set a breakpoint on read and/or write to the property
if that "internal only" instance variable were need to be exposed, it is a matter of copying the #property declaration itself; much less refactoring.
you can leverage the declarative power of all the various modifier keywords -- copy, strong, weak, atomic, etc.. -- which the compiler is taking more and more advantage of over thime
Even internally to a class, I generally lean to using properties and dot syntax to maintain state within the object. That isn't universally true -- there will be some instance variables that I directly manipulate (exclusively directly manipulate; no #property at all) if my design is such that exposure would imply a massive refactoring anyway.
so does the reason for using properties evaporate?
With ARC making the "ownership magic" available to ivars, this particular aspect of why one would choose properties over ivars does evaporate. However, many others remain:
atomic/nonatomic distinction is available for properties, not for ivars
flexibility afforded by properties (readonly/read+write distinction) is not available for ivars
ability to perform calculation and argument checking is not available to ivars
I continue using properties as my default way of keeping state that may be exposed to outside classes or internal "sibling" classes, because additional flexibility more than outweighs the small additional cost at run-time.
I don't think I've ever used properties simply because of memory management and I don't think you ever should. So to answer your question, no, there's no reason to use properties other than to access instance variables, which is essentially what they're supposed to be used for in the first place.
You are talking about two different things. ARC is for managing memory, so you don't have to be burdened with an abundance of dealloc and retain statements.
Properties are there to give a class the opportunity to control/limit exposure of its internal iVars, exposing an API for other classes to communicate/interact with.
Apart from retained there are also other modifiers that on occasions may become quite useful, e.g. 'copy' when assigning blocks to class member variables, or 'readonly' which ensures the property can't be written to. Also don't forget about 'dynamic' properties when working with Core Data, and the possibility to execute custom code when assigning or retrieving a property (when defining custom getters/setters instead of using #synthesize).

No ivars -> What am I missing?

I never use ivars. I only use properties -- sometimes assign properties with primitive types, and sometimes on a "private" class extension. I've seen the advantages of not using ivars in switching to ARC -- I have some borrowed code with lots of ivars that I still can't "ARC", since I don't know what needs to be retained. So I know some advantages of not using ivars, but what are the advantages of using ivars instead of properties?
Note: I depend exclusively on the ivars that are automagically added in (by the compiler?) for the property declaration.
Don't mark to close: I've looked at some of the other questions, like this and this and none hit the spot. The titles look good, but like so many questions on SO, the questions are a mess of strange doubts and other stuff.
Declared properties cannot be treated in the same manner as an #protected ivar. You can declare the property in a class extension to keep it private from any other class, or declare it in the header interface to make it publicly accessible, however there is no way to make it accessible only to subclasses. This would require the ivar declaration.
EDIT
Just another brief thought. I have recently been writing a lot of framework classes, and I think there might be something to be said for using iVars as documentation.
For example, let's say you are calling some code in a tight loop and you want to ensure that it is performant. Inside that tight loop you want to access a property of a class, but need to know whether each time you call it the return value is calculated on-the-fly or stored in an iVar. Seeing the iVar in the header is a quick way to ensure that you'll get that variable back without much overhead.
I don't see any reason to use iVars if you don't have to. If Apple and the compiler want to do work for you, I say let them. You'll have code that more efficient and easier to maintain. At this point iVars are legacy code.
One good reason for me: an annoying GCC bug, see this other question for a description.
If you're using Clang/LVVM, then you don't have to worry about this bug.