Up until now I thought that the #property directive generated a getter that ..alloc] init]'d its respective object, and now I don't understand why this is not part of the language. Even worse- there is no exception when a nil property is accessed.
I feel like there's a misconception somewhere in my reasoning, but I don't know where. I'd like to know why having a auto-lazy-instantiator as part of properties would not be ideal for almost all cases in Cocoa development.
Properties are a fairly new feature of Objective-C. A great deal of existing code assumes that ivars initialize to 0, and so object getters start as nil. The implementation of properties was built to implement the same type of accessors that most people had been writing by hand (or by using tools like Accessorizer). Most people did not create lazy getters by hand, so properties weren't implemented this way either. It's a specialized problem, not the common need.
(Side note: my claim here is somewhat belied by the fact that atomic was made the default, which was not the most common way to write accessors by hand. But it was compatible with common ways of writing accessors, just slower, and some people did routinely write atomic accessors. Laziness would not be compatible.)
There are many cases when you would not want this behavior at all. I wouldn't want an -image property to automatically generate an empty UIImage. I would rather get nil back if nothing is assigned. In many cases, there is a significant difference between "empty" and nil. A nil title may mean "use the default" while #"" might mean "be empty." This is a pretty common pattern. I don't write lazy accessors very often (but partially because it's a hassle to do so.)
There are several classes for which init is not the designated initializer, and may not even be a sensible (or even legal) initializer.
But it might be a useful option for properties, such as:
#property (nonatomic, lazy, readwrite, strong) NSMutableArray *stuff;
If you'd find that often useful, you should open a radar at bugreport.apple.com.
Regarding the fact it is legal to message nil in ObjC, that goes back to the very beginning. Often it's extremely handy (it gets rid of a lot of error-checking code). Sometimes it is the source of very annoying bugs (sometimes you still need to do the error-checking, and it's not always obvious when). But it is not likely to change. It's a fundamental part of the language.
Almost all standard read/write properties are assigned from outside the class. There is no need for lazy instantiation in such cases. The property simply holds whatever value may have been assigned. If no value is assigned, you get nil. This is all normal usage. So the normal synthesized getter returns whatever value may be assigned. The standard synthesized setter just holds on to the assigned value taking care of proper memory management and some KVO.
If you want a getter to return some internal, lazy loaded value, then that is a behavior that is specific to your need for that property. You need to implement your own custom getter to provide that behavior. This is far less common than most simple properties.
Related
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.
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.
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
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).
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.