views:

68

answers:

3

I have a class, let's call it ABC, with an NSArray *objects property, and the objects in the NSArray can be one of two different classes, X and Y. Both X and Y have a path property, but the compiler doesn't know this.

Therefore, even though ABC will always find the path property on my array objects, I get compiler warnings on my code -- "No 'path' method found". App runs fine but I'm getting annoyed by the warnings. How can I fix my code (with protocols?) so that the compiler stops complaining?

Thank you!

+1  A: 
valueForKey:@"path"
beefon
Brilliant, this worked great. I'm not sure why? But it did.
Elon
This is not brilliant - see Chuck's answer. It's using a very dynamic string-based way to access the method. It's sufficiently dynamic that the compiler is unable to warn for anything. If I saw this in code I was reading, I would be on guard that the author wasn't very experienced and was willing to get things to work by flailing.
Ken
Why not brilliant? I think KVC is very brilliant way to get things working in very beautiful way.
beefon
I think the reason it would be viewed as "not brilliant" is because it unnecessarily works around the language's error-checking. Purposely making your code more error-prone could be viewed as a bad thing. I don't personally mind it so much, but I don't think it's the best solution either.
Chuck
+2  A: 

Do both X and Y derive from the same super class that contains "path"? If "path" is conceptually the same value AND X and Y are related by this value, then it should either be in a super class or protocol.

Additionally you can use NSKeyValueCoding protocol to directly access values by string via - (id)valueForKey:(NSString *)key. You do lose any type safety using this method, however.

MarkPowell
I suppose they could, but in my case they don't. One is actually a CoreData managed object class and the other is a special-purpose class (dynamic images vs. static images).
Elon
+2  A: 

You need to import some header that declares a path method. When it's compiling your code, the compiler looks at the list of methods this file knows about and it sees that there is no path method. You just need to tell it that the method exists and its signature is whatever and the compiler will be satisfied. No protocol is necessary.

Chuck
When you do `objectAtIndex`, `NSArray` returns object with `id` type, so compiler can't know about methods in your class.
beefon
@beefon: You're partly right, but that doesn't change what I'm saying. The compiler does not know the class of the object, but it does know what methods it has seen in *any* class. If no visible class has declared a method, the compiler will tell you it hasn't seen any method that corresponds to the message you're sending, which is the warning that the OP saw.
Chuck
I'm confused -- both my class X (an NSManagedObject class) and my class Y (an NSObject subclass) have the path property declared in the header. Yet I was still getting the warning -- I think for the reason beefon adduces, that the compiler sees [objects objectAtIndex:0] as an id.
Elon
@Elon: An object typed as `id` can be sent any known message without a warning. That's the whole point of using `id` versus a static type. It will only warn if no currently visible class implements the method. Are you importing those classes' headers in the file where the warning is occurring?
Chuck
Aha, that was it. Wasn't importing the headers. This seems like the cleaner solution.
Elon