Custom getter side-effects - ios

Are there side-effects to calling a custom getter with dot notation?
I had been using a synthesized getter in Objective-C via the dot notation, i.e.
tree.fruitnumber
returned the number of fruits in tree. I had to customize the getter (for reasons not pertinent to this question). I wrote it as
-(int) fruitnumber
{
//climb into tree and hand count fruits. Get n;
return n;
}
Suprisingly, the dotted getter still works. Is this legit, or there is a nasty bug (which will infect all my fruits down the road (to the market?)).

Dot notation is really just syntactic-sugar for bracket notation. So both messages are the same:
int x = [self fruitNumber];
int x = self.fruitNumber;
The nice thing is, you can #synthesize your properties and the setter/getter methods will be built for you (depending on your property options, of course) but you can write your own instead and they will be used.
In the case where you are providing your own setters/getters, you can alternatively use the #dynamic propertyName line instead of #synthesize to tell the compiler these are being provided by you.

There's are some side effects that no one has mentioned:
Atomicity - if you don't declare a property as nonatomic, then (by default) it is an atomic property, which means that the value of the property will be full retrieved regardless of what other threads might be doing to mutate the property at the same time. If you have an atomic property and then override the getter or setter, you lose the atomicity (unless you implement it yourself).
Key-Value observation - by using the #synthesized methods, you are ensuring KVO compliance, which makes it very easy to observe values of the object as they change (and be notified of such changes). If you override the synthesized methods, you risk breaking that compliance.
So it is generally safe to override synthesized getters and setters, but there are caveats, and it is very important that you understand what they are so that if/when things break, you know why.

You can specify a custom getter when declaring the property, i.e.:
#property (readwrite, getter=numberOfFruitsCountedByTheCustomGetter) int fruitnumber;
In your implementation, synthesize it as usual:
#synthesize fruitnumber;
Then implement the getter:
- (int) numberOfFruitsCountedByTheCustomGetter {
return fruitnumber;
}

It doesn't matter whether you write the getter or it is synthesized, it gets called when you use the dotted notation (or the bracket notation). This is the way it is supposed to work.

The dot notation is just shorthand for calling the getter or setter method. There is no difference beyond how it looks.
A common side effect used in getters is a lazy getter.
-(id) something {
if ( nil == something ) {
something = ...;
}
return something;
}
A getter does not have to be related to a specific member. It can return the result of a calculation or lookup, or pass on something from a member object.

Progrmr is correct. However I'd consider putting in the #dynamic declaration to explicitly tell the compiler you are creating the getter. Here's a link to the documentation om properties. It's worth a wad if you have had a chance.
http://developer.apple.com/mac/library/iPad/index.html#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

Related

Confused about properties and ivars

I realize that there are already many property vs. ivar questions on here, but after doing a lot of research I can't seem to find a clear answer.
I understand that when you declare a property like the following, that the compiler automatically synthesizes the backing ivar and the two accessor methods for you:
#property NSString *myString;
What still confuses me is, is myString an actual instance variable? The reason I ask this is because you can never access it like this:
NSLog(#"Value of myString is: %#", myString);
You either have to use the backing ivar _myString, or one of the getter methods like [self myString] or self.myString. So I'm confused because normally you could just use the variable name plain and simple.
To top it all off, I've been told that you should not refer to myString as a property, and that the word property should only be used to refer to the two accessor methods that are synthesized for you by the compiler when you use the #property directive.
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it?
Any help clearing this up would be greatly appreciated. I've been struggling with solidifying the idea of properties and ivars being different things all day now.
Here are answer of your questions -
is myString an actual instance variable? - No
Would it really be wrong for you to say "I have a property called myString" , and if that is wrong then what would be the correct way to say it? - No its not wrong to call it.
So it looks like what actually confuses you is naming conventions, if you go through the naming conventions behind properties -
When you use the #property syntax to declare properties on an object, as described in “Encapsulating Data,” the compiler automatically synthesizes the relevant getter and setter methods (unless you indicate otherwise). If you need to provide your own accessor method implementations for any reason, it’s important to make sure that you use the right method names for a property in order for your methods to be called through dot syntax, for example.
Unless specified otherwise, a getter method should use the same name as the property. For a property called firstName, the accessor method should also be called firstName. The exception to this rule is for Boolean properties, for which the getter method should start with is. For a property called paused, for example, the getter method should be called isPaused.
The setter method for a property should use the form setPropertyName:. For a property called firstName, the setter method should be called setFirstName:; for a Boolean property called paused, the setter method should be called setPaused:.
Check the developer website for detailed description -
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
I'm pretty much a noob in objective c, but i understand it as follows:
As any other OOP language objective c has instance vars and getters+setters methods.
Basically every getter or setter looks the same, so XCode let you synthesize those automatically using the #property syntax.
In previous versions on XCode you had to declare both the ivar and its #property + #synthesize, but now the compiler does that for you.
This code:
#interface SomeClass : NSObject {
NSString* _myInstanceVar; //declare the ivar
}
#property (non-atomic, strong) myInstanceVar //declare the property+accessors
Is equivalent to this code:
#property (non-atomic, strong) myInstanceVar //declare the ivar+property+accessors
This documentation pretty much sums its up.
Hope i helped in anyway...

iOS pass NSArray in setter method possible

I try to write a custom setter method but I fail with the error message "Type of property 'pValue' does not match type of accessor 'setPValue:'". The array is passed successfully but I don't understand the the error message.
my .h-file:
#property (nonatomic, assign) double pValue;
- (double)getInverseCDFValue:(double)p;
- (void)setPValue:(NSArray*)aArray;
my implementation:
#synthesize pValue;
- (void)setPValue:(NSArray *)aArray {
double p = [[aArray objectAtIndex:22]doubleValue];
NSLog(#"p is: %f", p); //the value is written successfully
[self getInverseCDFValue:p]; //just calling another method for calculations
pValue = iCFDValue;
}
It works with passing single values but not with arrays. Is this not allowed in setter methods?
Thanks
When you synthesize your property, Xcode is going to generate setter and getter for your property unless your property is read-only. In this case, it's going to create only getter method for you. So, by naming convention, let's say you have a property name toto which type is double, your setter will be
-(void)setToto:(double d).
But what you can do is create another method set your property. But, you need to change your method name to something else. For example,
-(void)setTotoWithNSArray:(NSArray *).
You've defined a property pValue, which is of type double. Objective-C now expects that an accessor and a getter exist, with the names:
- (double)pValue; // Getter
- (void)setPValue:(double)value; // Setter
Either you let Objective-C autogenerate them for you, or you need to provide them explicitly.
Now you are providing a method with the same name, but a different type (NSArray). The type is different, and that's what the error message is telling you: the compiler thinks that the method is setter of your property, but you've given it the wrong type. It tells you because since you violate the expectations, the property cannot be used correctly in some contexts like Key-Value Coding. In almost all cases, what you've done is considered to be a bug.
You could make the pValue property read-only, I think that would make the warning disappear but it still would be bad because the type difference is confusing. Instead, rename the setter with the array argument to something else:
- (void)setPValueFromArray:(NSArray *)anArray;

Properties and their backing ivars

Hi imagine I have properties in the .h file:
#property (nonatomic) NSString * myText;
#property (nonatomic) SomeClass * someObj;
Now, in the class implementation.
Say, I didn't forget to use synthesize, and I called:
#synthesize myText, someObj;
Now say in code I forget to put self before the property name (and directly refer to the ivar):
myText = #"Hello";
someObj = [[SomeClass alloc] init];
My question is: is this a problem? What problems can it result in? Or it is no big deal?
ps. Say I am using ARC.
My question is: is this a problem?
This is called "direct ivar access". In some cases, it's not a problem, but a necessity. Initializers, dealloc, and accessors (setters/getters) are where you should be accessing self's ivars directly. In almost every other case, you would favor the accessor.
Directly accessing ivars of instances other than self should be avoided. Easy problem here is that you may read or write at an invalid address (undefined behavior), much like a C struct. When a messaged object is nil, the implementation of that message is not executed.
What problems can it result in?
Biggest two:
You won't get KVO notifications for these changes
And you are typically bypassing the implementation which provides the correct semantics (that can be justified). Semantics in this case may equate to memory management, copying, synchronization, or other consequences of a change of state. If, say, a setter is overridden, then you are bypassing any subclass override of that setter, which may leave the object in an inconsistent state.
See also: Why would you use an ivar?
For clarity, I recommend always using
self.propertyname
as opposed to
propertyname
as this removed any confusion between what variable belong to the class or have been declared locally above in the method.
To enforce this, try to avoid using #synthesize at all, which is only needed if you provide both custom getter and setter (but not one or the other)
The compiler automatically allows you to use _propertyname in the getter/setter (which is necessary to prevent recursive calls of the function)
You should not access the underlying instance variables by accident, only if you plan to do so.
Unexpected side effects may be that KVO doesn't work, overriding accessor methods are not called and the copyand atomic attributes have no effect.
You don't need to use #synthesize since Xcode 4.4, if you use default synthesis the compiler does an equivalent of
#synthesize myText = _myText;
so that
_myText = #"Hello";
self->_myText = #"Hello";
are equivalent and myText = #"Hello"; results in an "undefined identifier" compiler error.
If you use just #synthesize myText the compiler does (for backward compatibility reasons):
#synthesize myText = myText;
which is error prone.
Note that there are valid reasons to use the underlying instance variables instead of the accessor - but it's bad style to do this by accident.
For 30 years now, the recommended practice has been:
use getter/setter methods or the new . operator to read and write ivars.
only access ivars directly when you must.
pick ivar names to prevent accidentally using them, unless the ivar is one that will always be accessed directly (that is why the default behaviour and convention is to prefix ivars with an underscore).
You need to access ivars directly in a few situations:
Manual memory management requires it. You won't need this if ARC is enabled.
If you are going to read the variable variable millions of times in quick succession, and you can't assign it to a temporary variable for some reason.
When you're working with low level C API, it probably needs a pointer to the ivar, Apples libxml2 sample code accesses ivars directly for example.
When you are writing the getter or setter method yourself, instead of using the default #synthesize implementation. I personally do this all the time.
Aside from these situations (and a few others), do not access ivars directly. And prefix all ivars with an underscore, to make sure you don't accidentally access them and to prevent them appearing in xcode's autocomplete/intellisense while you code.
The two main reasons for the convention are:
Getter/setter methods and properties can be kept around when the underlaying memory structure of your class changes. If you rename an ivar, all code that reads the ivar will break, so best to have zero code or almost no code that accesses ivars directly.
Subclasses can override getters and setters. They cannot override ivars. Some people think subclasses shouldn't be allowed to override getters and setters - these people are wrong. Being able to override things is the entire point of creating a subclass.
Fundamental features like KVC and KVO can fall apart if you access ivars directly.
Of course, you can do whatever you want. But the convention has been around for decades now and it works. There is no reason not to follow it.
Contrary to what other answers seem to agree upon, I would recommend to always use direct ivar access unless you are very clear about what you are doing.
My reasoning is simple:
With ARC, it's not even more complicated to use direct property access, just assign a
value to the ivar and ARC takes care of the memory management.
(And this is my main point:) Property accessors may have side-effects.
This is not only true for property accessors you write, but may also be true for
subclasses of the class you are implementing.
Now these accessors defined in subclasses may very well rely on state that the subclass
sets up in it's initializer, which has not executed at this point, so you calling those
accessors might lead to anything from undefined state of your object to your application
throwing exceptions and crashing.
Now, not every class may be designed to be subclassed, but I think it's better to just use one style everywhere instead of being inconsistent depending on the class you are currently writing.
On a side note: I would also recommend to prefix the name of every ivar with an _, as the compiler will do automatically for your properties when you don't #synthesize them.

Difference between _ and self. in Objective-C

Is there a difference between using the underscore and using the self keyword in Objective-C when calling an #property?
Property declaration:
#property (weak, nonatomic) NSString *myString;
Calling #synthesize on the property:
#synthesize myString = _myString;
Is there a difference if I want to use it in my code? When? In the getter/setter?
self.myString = #"test";
_myString = #"test";
self.myString = #"test"; is exactly equivalent to writing [self setMyString:#"test"];. Both of these are calling a method.
You could have written that method yourself. It might look something like this:
- (void)setMyString:(NSString*)newString
{
_myString = newString;
}
Because you used #synthesize, you don't have to actually bother writing that method, you can just allow the compiler to write it for you.
So, from looking at that method, it looks like calling it will do the exact same thing as just assigning a value to the instance variable, right? Well, it's not so simple.
Firstly, you could write your own setter method. If you do so, your method would get called, and it could do all sorts of additional things as well as setting the variable. In that case, using self.myString = would call your method, but doing _myString = would not, and thus different functionality would be used.
Secondly, if you ever use Key Value Observing, the compiler does some very clever tricks. Behind the scenes, it subclasses your class, and overrides your setter method (whether it's one you wrote yourself or one generated by synthesize), in order to make the calls to willChangeValueForKey: that are needed for Key Value Observing to work. You don't need to know how this works (although it's quite interesting if you want some bedtime reading!), but you do need to know that if you want Key Value Observing to work automatically, you have to use setter methods.
Thirdly, calling the setter method even if you're relying on synthesize to write one gives you flexibility for the future. You might want to do something extra whenever a value is changed, and at the point you discover you want to do that, you can manually write a setter method — if you're in the habit of always using self.myString =, then you won't need to change the rest of your code to start calling the new method!
Fourthly, the same applies to subclasses. If someone else was to subclass your code, if you use the setters then they could override them to adjust the functionality.
Any time you access the instance variable directly, you're explicitly not providing a way for extra functionality to be hooked in at that point. Since you or someone else might want to hook in such functionality in the future, it pays to use the setters all the time, unless there's a good reason not to.
You are correct - the first version (self.myString) calls the synthesized getter/setter and the second version access the private member variable directly.
It looks like you are using ARC, so in that case it doesn't make that much of a difference. However, if you aren't using ARC, it can make a difference as assigning to the private member directly won't trigger the automatic retain/release or copy/release logic that is generated for you by using synthesize.
The _ (underscore) is simply a convention, as explained in this question.
When you don't prefix a property access with self., you are accessing the underlying variable directly, as in a c struct. In general, you should only ever do this in your init methods and in custom property accessors. This allows stuff like computed properties and KVC to work as intended.
There is a tip not mentionend, the access using underscore is faster and the access using self is safer (KVC). Maybe this can summarise when you have to use each one.

Automatic Reference Counting & Synthesized Properties

When using ARC for iOS, is there any difference between the following?
#property (strong, nonatomic) NSObject *someProperty;
...
#synthesize someProperty;
//and then in the init method, either:
self.someProperty = aProperty;
//or
someProperty = aProperty;
I know that without ARC, self.someProperty is actually calling the synthesized setter method which sends a retain message to the object. But now with ARC, does it matter if I use dot notation for setting a property like this?
More generally, does ARC truly mean that I don't have to worry about reference counts at all? Or are there certain situations in which the way I wrote my code could cause ARC to make a mistake?
The difference is the same as in the case without ARC: by using dot notation, you are calling the synthesized setter, and by assigning directly to the ivar, you are going around the setter method.
Under ARC, there are no differences in memory management between the two options but you should still make a conscious decision between the two options: assigning directly to the ivar bypasses KVO, for example, while going through the setter method is slightly slower but probably safer in most cases, e.g. when you later decide to make the property atomic or override the setter.
Personally, I would always use the property notation self.abc = ...; except possibly in init where it is often desirable to bypass KVO. In short, use the same reasoning you used before ARC.

Resources