NSMutableArray with only a particular type of objects - objective-c

is it possible to specify that a NSMutableArray can only contain a certain type of objects.
For example, if I want to store only this kind of objects :
#interface MyObject : NSObject {
UInt8 value;
}
In order to be able to use the instance variable like this :
- (void)myMethod:(NSMutableArray *)myArray{
for (id myObject in myArray){
[self otherMethod:myObject.value];
}
}
because I'm getting this error :
request for member 'value' in something not a structure or union
Thank you for your help

It sounds like you're coming from a Java/C# type background where limits can be imposed on collections.
Collections in Cocoa don't follow that pattern. There is no way to set a restriction on what type of objects can be inserted (unless you write a wrapper class that enforces this).
Objective-C, by design, follows the "if it walks like a duck and it quacks like a duck, then it most probably is a duck" philosophy. That is to say that rather than checking whether an object is a particular type, you should be checking whether it can do what you want it to do regardless of its type.
You can do this using respondsToSelector:.
Finally, your problem isn't actually related to the fact that the array has no restrictions. Your object doesn't appear to declare the instance variable value as a property, or expose any accessor methods for it.
This is why you're seeing the error when you try myObject.value. That syntax in Objective-C is how you access properties.
The default scope for instance variables in Objective-C is #protected, which means anything outside your class can't access them without going through an accessor method of some kind.
You need to declare and define the methods - (UInt8)value and - (void)setValue:(UInt8)aValue and use them.
Alternatively, you could declare it as a property.

You are getting that error, because for as far as Objective-C is concerned, myObject is of the non-type id, which doesn't support the value property. To make Objective-C aware of the fact it's always dealing with a MyObject in this loop, you'll have to tell it the myObject object is an instance of MyObject.
for (MyObject *myObject in myArray) {
Also, you have to make sure the value ivar is accessible using dot-notation by implementing getter and setter methods for it. You can do this yourself by implementing -value and -setValue:, or you can use #property and #synthesize to let Objective-C do this.

Objective-C doesn't work like that. You need to use [myObject value] (which will work irrespective of the kind of object, as long as it responds to -[value]. If you only want one type of objects in it, insert only that type of objects.

You would have to write a wrapper-class for the NSMutableArray, see for example this question.

Subclass NSMutableArray and override methods that mediate the addition of objects to the array. You would check the object type in these overridden methods, only calling [super addObject:xyz] if the type is accepted.

maybe you can use protocol:
#protocol Person <NSObject>
#end
#interface Person : NSObject <Person>
#end
to use:
NSArray<Person>* personArray;

Related

Key-Value Coding with a key of 'description'

I am using Key-Value Coding to simplify updating instances of a model class:
#interface NewsItem : NSObject
{
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *description;
#property (nonatomic, copy) NSString *link;
#property (nonatomic, copy) NSString *date;
using:
SEL selectorName = NSSelectorFromString(elementName);
if ([self.newsItem respondsToSelector:selectorName])
{
NSString *sanitisedElement = [self sanitiseElement:self.currentElementData];
[self.newsItem setValue:sanitisedElement forKey:elementName];
}
This works well but the 'description' property doesn't 'smell' right to me as it has overridden the base NSObject description getter (+ (NSString *)description). If the description getter is invoked now it will return irrelevant information when the caller would be expecting a description of the class.
Is it possible to safely proceed with Key-Value Coding for this class (given that I am bound to these property names by the external data source)? Or would it be wise to change the property names and manually check keys/set values instead?
You could override description in your class. This method is usually used only for debugging
and no caller can expect a specific output of that method.
But I see more general problems in your code. It is only checked that a method with the
given name exists. This does not imply that this method corresponds to a property, and even then, it does not imply that there is a setter for that property.
For example, every NSObject responds to the selector "init", so if the external
data source sends that key as "elementName", your code would immediately crash.
Therefore, an explicit list of "known keys" is needed. But then you can as well
use a mapping (NSDictionary) from external element names to internal properties
to avoid any conflicts.
I think that you are confusing methods with properties, and you are making things more complicated that how they are.
Is enough that, given an elementName that contains directly the setter name (i.e.: setDate), you invoke the selector passing that argument the object argument:
SEL selectorName = NSSelectorFromString(elementName); // elementName something like "setDate"
if ([self.newsItem respondsToSelector:selectorName])
{
[self.newsItem performSelector: selectorName withObject: sanitisedElement];
}
As for the description method, it has overridden NSObject's description, so you have two choices: name it in another way, or leave it like it is, and invoke it on super when you need the object description, with the help of Objective-C runtime:
struct objc_super superclass= { self.newItem, [self.newItem superclass] };
NSString* desc= objc_msgSendSuper(&superclass, #selector(description));
You can always override inherited methods.
By creating a property whose getter is the same as the signature of An inherited method, you are overriding it.
Is it bad? Yes if your implementation is not useful for debugging.
As best practice for KVC and KVO purposes it is a good idea to avoid potentially clashing with common inherited methods properties and ivars.
The common approach to this is to make longer property and method names and to make them more likely to be unique. One common way is by prefixing all yours with an abbreviation common to your class or framework or code.
Using something commonly used by Apple is likely to bite you in a rare and hard to debug way.
It's especially a bad idea to do this when core data is involved.
Don't be reluctant to make things longer. Code completion will type for you. Plus, a nice side effect of class specific prefixing is pseudo not only the pseudo namespace but that your class specific properties, variables, constants and methods will bubble up first in code completion.

What's the difference between KVC and Properties?

So, I've already read up on the documentation which notes
Objective-C 2.0’s dot syntax and key-value coding are orthogonal technologies. You can use key-value coding whether or not you use the dot syntax, and you can use the dot syntax whether or not you use KVC. Both, though, make use of a “dot syntax.” In the case of key-value coding, the syntax is used to delimit elements in a key path. It is important to remember that when you access a property using the dot syntax, you invoke the receiver’s standard accessor methods.
It then provided an example that supposedly showed the difference between the two. However, I still don't get, what's the difference between KVC and property accessor methods? Aren't they the same? And how do I distinguish between dots that call setValue:forKeyPath: and simple accessors?
However, I still don't get, what's the difference between KVC and property accessor methods?
KVC is a way to call property accessor methods, or otherwise access a property.
What do I mean by “otherwise access”? For KVC purposes, an instance variable with no accessor methods counts as an informal property. It'll get or set the value of the instance variable directly if no matching accessor pair can be found. (Yes, this is not worth using in modern code. Always declare an #property for anything you intend to access elsewhere, and, inversely, don't use KVC to access anything that isn't a public property.)
Property accessor methods are what KVC will call if they exist (preferred, both by KVC and by every sane programmer, over direct ivar access). An accessor may get or set an instance variable, as synthesized accessors do, or access some other storage.
Accessors are implementation, properties are interface, and KVC is one way to use them.
And how do I distinguish between dots that call setValue:forKeyPath: and simple accessors?
A key path is a string, whereas a property-access expression is an expression. The compiler evaluates a property-access expression and translates it into one or more Objective-C messages, whereas a key path is evaluated by KVC at run time.
So, when you use a key path:
[someObject setValue:theValue forKeyPath:#"foo.bar.baz"];
You know it's a key path because (1) it's a string, as indicated in this case by the string-literal syntax #"…", and (2) you're passing the key-path string to setValue:forKeyPath: for it to evaluate.
Using a key path is using KVC to access the named properties. It will send any relevant accessor messages on your behalf.
When you use a property-access expression:
someObject.foo.bar.baz = theValue;
You know it's a property access expression because you are not identifying the properties with a string. You are accessing them (sending the accessor messages) yourself, in your own code.
There isn't much reason to use KVC in any form; when you know the property at authorship/compile time, it's best to have an #property declared and to access the property yourself, whether with property-access expressions or message expressions ([[[someObject foo] bar] setBaz:theValue]). The time to use KVC is when you don't know what property you want to access until run time, which is pretty rare. It's mainly a building-block technology behind KVO, Cocoa Bindings, parts of Core Animation, etc.
Mostly, you'll only want to access properties yourself.
Key value coding allows you to set and get the value of properties through code using the string name of the property. For example, if I had a property named foo which is of type NSString:
[self setValue:#"mystring" forKey:#"foo"];
// read the value by key
NSString *s = [self valueForKey:#"foo"];
Dot syntax is compile syntax sugar. As a personal preference (as some don't agree - fine) I don't use dot syntax but I still use KVC:
[myObj setFoo: #"someString"]
equals:
myObj.foo = #"someString";
They are orthogonal, different concepts but both dealing with how you interact with properties
Finally, you mention property syntax. Yet another orthogonal concept but related to dealing with properties.
With objective-c, convention is important. Follow them. Properties are the name of the property for the get and set[Name] for the assignment:
- (NSString*)foo
{
return _foo; // defined as (NSString*)_foo in header
}
- (void) setFoo: (NSString*)foo
{
if (foo == _foo)
return;
NSString* curr = _foo;
_foo = [foo retain];
[curr release];
}
Now, who wants to write something like that every time. So, enter #property syntax:
In header:
#property (retain) NSString *foo;
Then in .m:
#synthesize foo;
That's the equivalent of the hand written property accessors. It's compiler syntax sugar which expands the property code based on how you attribute the properties.
Docs:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

Objective-C synthesize property name overriding

I am trying to understand the purpose of the synthesize directive with property name overriding. Say that I have an interface defined as follow:
#interface Dummy ... {
UILabel *_dummyLabel;
}
#property (retain, nonatomic) UILabel *dummyLabel;
And in the implementation file, I have:
#synthesize dummyLabel = _dummyLabel;
From what i understand, "dummyLabel" is just an alias of the instance variable "_dummyLabel". Is there any difference between self._dummyLabel and self.dummyLabel?
Yes. self._dummyLabel is undefined, however _dummyLabel is not.
Dot syntax expands out to simple method invocations, so it's not specific to properties. If you have a method called -(id)someObject, for example in the case of object.someObject, it will be as if you wrote [object someObject];.
self.dummyLabel //works
self._dummyLabel //does not work
dummyLabel //does not work
_dummyLabel //works
[self dummyLabel]; //works
[self _dummyLabel]; //does not work
Your understanding is incorrect. dummyLabel is the name of the property, and is not an alias for the instance variable - the instance variable is only called _dummyLabel. So the following holds for an instance of Dummy called myObject:
[myObject dummyLabel] works
myObject.dummyLabel works
[myObject _dummyLabel] fails
myObject._dummyLabel fails
myObject->dummyLabel fails
myObject->_dummyLabel depends on the visibility of the ivar (#public, #private, #protected)
[myObject valueForKey: #"dummyLabel"] works
[myObject valueForKey: #"_dummyLabel"] depends on the implementation of +accessInstanceVariablesDirectly (i.e. it will work in the default case where +accessInstanceVariablesDirectly returns YES).
The advantage of having another name
for the ivar than for the property is
that you can easily see in the code
when you are accessing one or the
other - Andre K
I'm not able to find a 'comment' button so I'm having to post as an 'answer'.
Just wanted to expand on Andre's comment - by knowing when you are using the synthesized properties vs the vanilla variable, you know (especially in case of setters) when a variable is being retained/copied/released automatically thanks to your nice setter, vs being manipulated by hand.
Of course if you are doing things right, you probably don't need the help of a setter to retain/release objects properly! But there can be other scenarios too where referring to your ivars as self.ivar instead of _ivar can be helpful, such as when you are using custom setters/getters instead of the default synthesized ones. Perhaps every time you modify a property, you also want to store it to NSUserDefaults. So you might have some code like this:
#interface SOUserSettings : NSObject {
BOOL _autoLoginOn;
}
#property (nonatomic, assign) BOOL autoLoginOn;
#end
#implementation SOUserSettings
#synthesize autoLoginOn = _autoLoginOn;
- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {
_autoLoginOn = newAutoLoginOnValue;
[[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:#"UserPrefAutoLoginOn"];
}
#end
Note: This is just illustrative code, there could be a thousand things wrong with it!
So now, in your code, if you have a line that says _autoLoginOn = YES - you know it's not going to be saved to NSUserDefaults, whereas if you use self.autoLoginOn = YES you know exactly what's going to happen.
The difference between _autoLoginOn and self.autoLoginOn is more than just semantic.
I don't see any big advantage of
renaming _dummyLabel to dummyLabel
In some ObjC runtimes you have a hard time making instance variables invisible to users of the class. For them sticking some prefix (or suffix) on your instance variables can make it clear (or more clear) that you don't want anyone messing with your variables. However you don't want that gunk on your public functions. This lets you get it off.
It could also be useful if you need to maintain an old interface with one set of names at the same time as a new set of APIs with a new set of names (setLastname vs. setSurname).
Old post, but I think its important to mention, that it is recommended to access variables via getters and setters (so, with dot notation). Accessing a field directly (_ivar) is strongly recommended only when initializing it.
There is some good Apple's article:
https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
Last paragraph:
You should always access the instance variables directly from within
an initialization method because at the time a property is set, the
rest of the object may not yet be completely initialized. Even if you
don’t provide custom accessor methods or know of any side effects from
within your own class, a future subclass may very well override the
behavior.

Using (id) in Objective-C

I have a function that I want to operate on two different custom objects. My first thought was to accept the argument as an (id) and operate on the id object. I can't quite seem to figure out how to do that, however.
Both classes (say apples and oranges) have interface variables:
NSDecimalNumber *count;
I want to do something similar to this:
-(NSDecimalNumber*)addCount:(id)addObject{
return [count decimalNumberByAdding:addObject.count];
}
I can't seem to figure out the syntax to make that happen. Is this the proper approach, or would it be better to subclass (from say a fruit class) and operate on the parent class?
-(NSDecimalNumber*)addCount:(Fruit*)addFruit{
return [count decimalNumberByAdding:addFruit.count];
}
While you can send a message to any object (id) - property accessors require that the compiler be aware of the type you are dealing with - this is because property accessors are syntactic sugar around calling specific getter and setter methods.
You have a few of ways of working around this:
Instead of accessing the count property, call the corresponding [getCount] methods.
If the different classes have different versions of this method, you can use a runtime type check:
Provide a base class for both types so that you can pass in something more specific than (id).
Define and implement a Protocol that both objects implement that defines a count property (or method).
Example of a dynamic type check:
if( [object isKindOfClass:[Apple Class] )
// call one overload of getCount
else if( [object isKindOfClass:[Orange Class] )
// call another overload of getCount
Personally, I favor strong typing in my code because it makes it easier to understand the intent. It also allows the IDE to support your coding effort with intellisense, static analysis, and refactoring features. So, in your case, I would use either #3 or #4 as an approach - depending on whether inheritance is really appropriate for the problem.
You should try not to access instance variables from another class.
In Objective-C it's enough that the two objects respond to the same selector (say count), however that would give you a compiler warning.
There are two ways you can get rid of this warning: either by subclassing from a common Fruit class or by having your two classes conform to a protocol. I'd go with the protocol:
#protocol FruitProtocol
- (NSDecimalNumber *)count;
#end
#interface Orange : NSObject<FruitProtocol>
#end
#interface Apple : NSObject<FruitProtocol>
#end
Then your method can look like this:
-(NSDecimalNumber*)addCount:(id<FruitProtocol>)addFruit {
return [count decimalNumberByAdding:[addFruit count]];
}
Here you are saying that your addCount expects any object that conforms to the FruitProtocol protocol, and hence can respond to the count selector, so the compiler will accept it.
The fact that you are trying to access 'addFruit.count' is the problem. The dot syntax is only for properties declared with #property (or for structs). If you change it to
[addFruit count]
and add
-(NSDecimalNumber*)count
{
return [[count retain] autorelease];
}
to each class, then it would work. However, you will notice you'll get a warning saying 'id' may not respond to the 'count' message, and unless you can be absolutely sure the items sent to this method implement a 'count' method, this is a problematic approach.
I agree with pgb's approach. You should define a protocol, and declare both classes to implement that protocol. This eliminates the problem of not knowing whether the object will respond to 'count' or not, as you now have a 'contract' of sorts.
If you want to keep the dot syntax with a property, you can declare it in the protocol:
#protocol FruitProtocol
#property(readonly) NSDecimalNumber * count;
- (NSDecimalNumber *)count
#end
and then, your function would be:
-(NSDecimalNumber*)addCount:(id<FruitProtocol>)addObject{
return [count decimalNumberByAdding:addObject.count];
}
You're sending the message to count, what is count? id is a pointer to any type of object. If you expect the object to have a count property, then you should only be able to pass in an Array (or some other type restriction).
-(NSDecimalNumber*)addCount:(NSArray*) Object{
return [count decimalNumberByAdding: [Object count]];
}
As I understand it, id does not have any methods or variables associated with it because it is a generic pointer that does not refer to any specific class. This page has some good info on ids if you scroll down a bit.
anObject this will not have a count variable, which is why your first attempt won't work. Creating a base class and using that as a parameter to the method seems like the best idea to me.

What's the difference between declaring a variable "id" and "NSObject *"?

In Objective-C, what's the difference between declaring a variable id versus declaring it NSObject *?
With a variable typed id, you can send it any known message and the compiler will not complain. With a variable typed NSObject *, you can only send it messages declared by NSObject (not methods of any subclass) or else it will generate a warning. In general, id is what you want.
Further explanation: All objects are essentially of type id. The point of declaring a static type is to tell the compiler, "Assume that this object is a member of this class." So if you send it a message that the class doesn't declare, the compiler can tell you, "Wait, that object isn't supposed to get that message!" Also, if two classes have methods with the same name but different signatures (that is, argument or return types), it can guess which method you mean by the class you've declared for the variable. If it's declared as id, the compiler will just throw its hands up and tell you, "OK, I don't have enough information here. I'm picking a method signature at random." (This generally won't be helped by declaring NSObject*, though. Usually the conflict is between two more specific classes.)
id means "an object", NSObject * means "an instance of NSObject or one of its subclasses". There are objects in Objective-C which are not NSObjects (the ones you'll meet in Cocoa at the moment are NSProxy, Protocol and Class). If some code expects an object of a particular class, declaring that helps the compiler check that you're using it properly. If you really can take "any object" - for instance you are declaring a delegate and will test all method sends with respondsToSelector: calls - you can use an id.
Another way to declare an object variable is like "id <NSObject>", which means "any object which implements the NSObject protocol.
From my limited understanding of Objective-C, not all objects are derived from NSObject (unlike Java where all objects derive from Object). You can theoretically have other root objects. id could apply to any of those non-NSObject derived objects.
I would like to add another difference. When you add a protocol to id, it does not longer mean that it will be of type NSObject *, it just means that it will be any class that confirms to that protocol.
So, for example, this code will not throw any error, since NSObject's category NSDelayedPerforming has that method:
id testId;
[testId performSelector:#selector(isKindOfClass:) withObject:[NSObject class] afterDelay:.5];
However, this code will show the error No known instance method for selector "performSelector:withObject:afterDelay:":
id<NSMutableCopying> testId;
[testId performSelector:#selector(isKindOfClass:) withObject:[NSObject class] afterDelay:.5];