KVO: observing global NSNumber - objective-c

I have static global NSNumber value and i need to observe it. If it was member of some object, i would have no problems whatsoever. But what do i do with global scope? I guess i could use
[globalVar addObserver:self forKeyPath:**integerValue** options:... ]
but that seems ugly because i might as well use "intValue" KeyPath and i need to observe NSNumber, not it's int part, even if it's the only part of it i''m using now. Making this particular variable part of some class doesn't seem like a "right" think to do. Thanks!

Easy answer: you can't. Observing is a software mechanism which fundamentally involves method calls, doing a store (i.e. a machine instruction) into a global variable provides no hook to hang the mechanism on.
The best option is to re-think your design. Think of storing the value in a singleton class and accessing/observing it there.
Hard answer: write your own mutable version of NSNumber (an instance of which is immutable) and have this class implement the key-value observing protocol (this class might just be a wrapper with an NSNumber instance variable). Now store and instance of this class in your global variable and add any observers you like to it.

The usual way to do this kind of thing is by making it a value reachable from some globally-available object, such as NSApp, or its delegate.

CRD is right, "In KVO only the property is observed, not the value" Typically dictionaries or custom objects are KVO but not the leaves (values) themselves (numbers, strings). Facing a similar problem, I finally extended the NSNumber class making it KVO compliant.
Now if you are looking for different approaches to achieve notifications in your app, I would strongly suggest to read this article.

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.

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 ;-)

How to inherit from NSDictionary?

I have an object called Settings that inherits from NSMutableDictionary. When I try to initialize this object using
Settings *settings = [[Settings alloc] initWithContentsOfFile: #"someFile"]
it returns an object of type NSCFDictionary. As a result, it doesn't recognize my additional methods. For example, when I call the selector "save", it objects:
[NSCFDictionary save]: unrecognized selector sent to instance 0x524bc0
Of course, it's OK when I initialize using the garden variety
Settings *settings = [[Settings alloc] init]
I tried to cast it again to Settings but that didn't work. This seems really simple - what am I missing?
Thanks
NSDictionary is a class cluster. This means that the value returned from its init methods is not strictly an NSDictionary, but a subclass that implements the actual functionality. In almost every case, it is better to give your class an NSDictionary as an instance variable or to simply define a category on NSDictionary.
Chuck is correct about NSDictionary (and Dave, by extension, about NSArray/Set/String) and class clusters. Odds are that -[NSDictionary initWithContentsOfFile:] calls down to a different initializer than -init does, which is why it swaps out your allocated Settings instance for another subclass of NSMutableDictionary. (The initialization action when reading from a file may select a particular known subclass of NSDictionary which performs well for loading from a file, etc.)
I'll echo Chuck's guidance that it is almost always better to use composition or categories than inheritance for an NSDictionary. It's highly likely that you could accomplish what you're doing with categories in a much simpler way, and expose yourself to fewer potential bugs in the process. Consider yourself warned before deciding to subclass.
That being said, both NSDictionary and NSMutableDictionary have been designed to support subclassing, and on rare occasions that's the right thing to do. Think long and hard about it before trying it. If you find it's the right choice for your design, here are some key points to know and do as needed:
Override the following primitive methods from NSDictionary:
-count
-objectForKey:
-keyEnumerator
-initWithObjects:forKeys:count: (designated initializer)
Override the following primitive methods from NSMutableDictionary:
-setObject:forKey:
-removeObjectForKey:
If you're supporting NSCoding, be aware of classForKeyedArchiver and replacementObjectForKeyedArchiver: (both instance methods from NSObject) — they can totally change how your class responds, and you often unintentionally inherit some odd behavior from NS(Mutable)Dictionary. (You can verify if they are the culprit by setting a breakpoint on them, or implementing them to call super and breaking on your own code.)
I've implemented a number of these points in an NSMutableDictionary subclass of my own. You can check it out and use the code however may be helpful to you. One that particularly helped me (and could be the solution for your problem) was overloading the designated initializer, which is currently undocumented (Radar #7046209).
The thing to remember is that even though these bullets cover most common uses, there are always edge cases and less common functionality to account for. For example, -isEqual: and -hash for testing equality, etc.
If you actually read the spec for NSDictionary (a rash action, I know) you'll find a section named "Subclassing Notes". In it you will read:
If you do need to subclass NSDictionary, you need to take into account
that is represented by a Class cluster—there are therefore several
primitive methods upon which the methods are conceptually based:
initWithObjects:forKeys:
count
objectForKey:
keyEnumerator
In a subclass, you must override all these methods.
From https://stackoverflow.com/a/1191351/467588, this is what I did to make a subclass of NSDictionary works. I just declare an NSDictionary as an instance variable of my class and add some more required methods. I don't know what to call them though.
I posted my code sample here https://stackoverflow.com/a/10993594/467588.
This question is very old, and since most of these answers were posted, Apple has introduced object subscripting, which allows you to make your own classes behave more like NSMutableArray or NSMutableDictionary. This is simpler than the alternatives discussed above.
At a minimum, you have to override these methods:
//Array-style
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
//Dictionary-style
- (id)objectForKeyedSubscript:(id <NSCopying>)key;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key;
Here's a nice tutorial on how to do just that.