KVC setNilValueForKey: recommends calling method and not using property accessor - objective-c

The KVC Documentation says
The key-value coding method setNilValueForKey: method is called when you attempt to set an attribute to nil.
Sounds good so far
... uses setValue:forKey: to set the new value. This maintains encapsulation of the model and ensures that any additional actions that should occur as a result of setting the value will actually occur. This is considered better practice than calling an accessor method or setting an instance variable directly.
Why is it better practice to call the -setValue:forKey: inside the -setNilValueForKey: method when setting a 'default' value on a primitive or value type property? Is there a performance or technical advantage to using the KVC method -setValue:forKey: opposed to the property accessor (I'm assuming that when it says accessor method it applies to accessor properties as well since they're just syntatic sugar over the method)? Usually when Apple recommends a 'best practice' there is a performance or reliability concern backing it. Does anybody know a documented reason why?

From your quote:
This maintains encapsulation of the model and ensures that any additional actions that should occur as a result of setting the value will actually occur.
Calling setValue:forKey: instead of an accessor or changing the ivar ensures that all proper side effects are maintained. When the quote mentions maintaining encapsulation, it means staying in KVC methods instead of custom accessors. Calling setValue:forKey: also means that you get the runtime to decide how the property should be set for you. Finally, the "additional actions" is probably referring to key-value observing. It will make sure the right methods are called, and not any that shouldn't be called.

Related

Use property in class extension instead of ivar in post ARC

The recommended practice is to use property, including private ones through class extension instead of ivar (except in init and dealloc) in the post ARC environment.
Aside from it being a recommended practice, what are the main drawbacks in someone using ivar instead of property? I am trying to convince some folks to make the switch but some have argued ivar works just as well and faster. So I would like to collect good solid arguments rather than giving soft statements such as "it's better, more consistent, etc."
There is no right answer to your question, just opinions. So you'll get varying answers, here's one to add to your collection :-)
Using private properties is is not recommended practice, it is largely a fad. :-)
A public property is part of the encapsulation of the class - how a property (or method) is implemented is not relevant to the user, only the behaviour.
A class does not need to hide how it is implemented from itself!
So the only use cases for private properties is where they provide some behaviour in a convenient way to the implementation of the class, not to hide that behaviour.
A private property with the copy attribute may be convenient if the class is, say, obtaining mutable strings from another class and needs to preserve their current values.
If the class wishes to lazily construct a value if it is needed but keep it after that time then a property can handle that conveniently. Of course a method or function can as well as a property is after all just a method call.
To make the choice think convenience/code design rather than encapsulation as you do for public properties. And most of the time you'll probably just use instance variables, just as you just use local variables.
HTH
There is not much difference in terms of performance. In reality, properties are instance variables with the accessors generated. So the reason why you want to do properties is because the code to generate the KVO notifications and the setter/getter methods are generated to you. So you have less time doing repetitive code on all your classes.
There are a few cases where using a private property is better or required over using an instance variable:
KVO - Since KVO requires getter/setter methods to do the work, you need a property (technically just the methods). Using KVO on a private property probably isn't too common.
Lazy loading or other "business logic" around the value. Using a property with custom setter/getter methods allows you to apply lazy loading and/or other logic/validation around the value.
Access to the value inside a block using a weak reference.
The last point is best covered with an example. As many people know, under certain conditions you can create a reference cycle in a block and this can be broken using a weak reference to self. The problem is that you can't access an ivar using the weak reference so you need a property.
__weak typeof(self) weakSelf = self;
[self.something someReferenceCycleBlock:^{
weakSelf->_someIvar = ... // this gives an error
weakSelf.someProperty = ... // this is fine
}];
Basically, use an ivar if none of these points will ever apply. Use private properties if any of these may apply over the lifetime of the class.

Why don't properties lazily instantiate by default?

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.

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.

Can I make an NSInteger an optional parameter on a method?

I would like to have a method along the lines of
setData:(SomeClassName *)data inPosition:(NSInteger)position
and in the implementation, check for nil as position. The idea is that if the position is provided, I will use it, and if not, I will allocate it automatically.
The problem is I can't pass either NULL or nil into this without a compiler warning.
I believe I have seen this pattern elsewhere (optional parameters). I think it might have been related to an NSIndexPath.
Should I use an NSNumber as a wrapper? or is there some other secret?
As an aside, I considered using separate methods - setData: and setData:inPosition:. But the problem is that 'data' is a core data created attribute, not a regular ivar, so when I actually want to set the value I would have to remember to send all the KVO messages. For example, inside setData:withPosition, I can't call the standard setData: - it would overwrite any work I did with the position.
Would also be interested in knowing which is the 'better' solution of these two.
#Justin's approach is generally the most appropriate. However, to your question about setData: and KVO, there are several things to note:
KVO notifications are sent automatically as long as the method is named setFoo:. Even if you override setFoo:, KVO will wrap your implementation with the correct KVO notification calls for the property. This is very likely the most magical thing in Cocoa. (I used to be certain it was the most magical thing, but I'm starting to wonder about block variable scoping, and especially how blocks are moved from the stack to the heap; that may be more magical.)
If you need to set a Core Data attribute directly, bypassing KVO and every other piece of possible magic, you can use the primitive accessor. setPrimitiveData: is the underlying method that setData: uses to set the property. You should not override the primitive accessors.
#Justin appears to have deleted his answer. The typical solution here would be to declare setData: and setData:inPosition: (btw, as a reader, I have no idea what "inPosition" means. I hope that it makes sense in context). setData: would call setData:inPosition: applying whatever is necessary to figure out "position."
Using the NSNumber wrapper is pretty standard.
Of course, you could always pass -1, NSNotFound, or define your own n/a value too.
There are three options:
Pass -1 or some such for "no value"
Use an NSNumber wrapper and pass nil for "no value"
Overload
You could try to use the Objective-C optional parameter mechanism, but that requires some sort of sentinel to mark the end of the list, so it's no better than any of the others.

Mutable vs immutable object for instance variable in objective C

I have a class with a property sampleNames. It is of type NSSet. The instance variable I plan to use will be NSMutableSet.
the only reason I have for using NSMutableSet is convenience for myself. But I recall being 'told' that Mutable class should be used as sparingly as possible for some reason I cannot remember. I understand how to use both ways, so this si not so much a question about that.
What are the practical considerations when deciding whether or not to use a mutable class internally?
Please note, I am not at all interested in changing my PROPERTY to NSMutableSet. But the fact that I am using a different type internally made me think about why and I have no real justification other than convenience, Which I have found to be a bad justification by itself. Maybe it is the only reason, but i am not actively aware of what I am trading for the convenience.)
I think you are confused.
You use NSMutableSet when you need to change the contents of the set. You can only do that if it is mutable.
If you use NSSet, then you can't change the contents.
So ... your property declaration and your instance variable should be the SAME class. Either use NSSet if you don't need to change the contents or NSMutableSet if you do.
Having a different class for the property and the instance variable is a recipe for disaster ... it's not convenient and it is confusing = BAD ;-)