Objective-c: Reference to ivar persistent? Good idea? - objective-c

I have a situation where I'm keeping references to ivars which need to be persistent. In one object, I have an array of pointers to ivars in another object, which are used over the entire lifetime of the program. In other words, I'm not just passing a reference to retrieve a value -- I'm keeping the pointers around.
Is this a valid? Is it possible that the ivars might move? Are there cases where objects instantiated objects are moved around at runtime unbeknownst to the program? Or, do objects stay exactly where they are created. If the later is the case, is there any reason not to use references the way I am?
I'm using ARC.
Note: This probably wasn't a good way to design this to begin with, but... it's all done and working 99%! (except for a nasty crash which reboots the entire phone... )

Objects and their instance variables don't move once created. However, you also need to keep a strong reference to the object that holds the ivar. Otherwise, the object might be deallocated, leaving you with a dangling pointer.
Note that it is generally a very bad idea to have pointers to another object's insntance variables.

While there's no technical problem with accessing the ivars from outside (as rob stated) there's still the architectural design to consider: The approach you've taken breaks encapsulation. Additionally it is very uncommon for Objective-C.
So regarding maintainability of your code I would recommend to refactor the code. In Objective-C there's no friend declaration as in C++, so it's unusual to access ivars from outside the declaring class.

Let's say an object of class A wants to access the ivars of an object of class B persistently (in your example).
What you normally do is create a property (with the strong annotation, like #property (strong) ClassB *myBVar) in class A to reference an object of class B.
If you want to set or read B's properties you use the dot notation or call the getter/setter methods:
myBVar.name = #"Jim";
NSLog(#"Name:%#",myBVar.name);
[myBVar setName:#"Jim"];
NSLog(#"Name:%#",[myBVar name]);
You never call a ivar directly as it's implementation might change.

Related

Objective C - Using property get accessor vs directly using iVar

I was wondering what exactly are the differences between using the (get) accessor for reading the value of property and directly using the iVar?
Say I have a class which declares a property:
#interface Foo : NSObject
#property (strong) NSString *someString;
#end
And in the implementation I'm using it. Are there any differences between the following two lines:
someLabel.text = self.someString;
someLabel.text = _someString;
For set accessors it's clear. Afaik for strong properties the accessor takes care of retain and release (an interesting 'side question' would be if ARC changes that, i.e. does setting the iVar directly [assuming it's not an __weak iVar] also retain and release correctly using ARC), also KVO requires the use of accessors to work properly etc. But what about getters?
And if there's no difference, is there one way considered best practice?
Thx
As you know, calling self.someString is really [self someString]. If you chose to create a property then you should use the property. There may be other semantics added to the property. Perhaps the property is lazy loaded. Perhaps the property doesn't use an ivar. Perhaps there is some other needed side effect to calling the property's getter. Maybe there isn't now but maybe this changes in the future. Calling the property now makes your code a little more future proof.
If you have an ivar and a property, use the property unless you have explicit reason to use the ivar instead. There may be a case where you don't want any of the extra semantics or side effect of the property to be performed. So in such a case, using the ivar directly is better.
But ultimately, it's your code, your property, your ivar. You know why you added a property. You know any potential benefits of that property, if any.
I think this what you are looking for. Why use getters and setters?
There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.
Here are the some of the reasons I am aware of:
Encapsulation of behavior associated with getting or setting the
property - this allows additional functionality (like validation) to
be added more easily later.
Hiding the internal representation of the
property while exposing a property using an alternative
representation.
Insulating your public interface from change -
allowing the public interface to remain constant while the
implementation changes without effecting existing consumers.
Controlling the lifetime and memory management (disposal) semantics
of the property - particularly important in non-managed memory
environments (like C++ or Objective-C).
Providing a debugging
interception point for when a property changes at runtime - debugging
when and where a property changed to a particular value can be quite
difficult without this in some languages.
Improved interoperability
with libraries that are designed to operate against property
getter/setters - Mocking, Serialization, and WPF come to mind.
Allowing inheritors to change the semantics of how the property
behaves and is exposed by overriding the getter/setter methods.
Allowing the getter/setter to be passed around as lambda expressions
rather than values.
Getters and setters can allow different access
levels - for example the get may be public, but the set could be
protected.
I am not a very experienced person to answer this question, even though I am trying to give my views and my experience by seeing source code which is around 10yrs older.
In earlier codes they were creating ivars and property/synthesise. Nowadays only property/synthesise is used.One benefit I see is of less code and no confusion.
Confusion!!! Yes, if ivars and its property are of different name, it does create a confusion to other person or even to you if you are reading your own code after a while. So use one name for ivar and property.
By using property KVO/KVB/KVC are handled automatically, thats for sure.
#property/#synthesise sets your ivar to 0/nil etc.
Also helpful if your subclass contains same ivar.
For mutable objects Dont make properties.

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

Objective-C class without properties?

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.

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.