Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Colin Jackson
Colin Jackson
4,829 Points

Method call on wrong class instance from valueForKey return (Ribbit)

Hi all! I have a question about making method calls on the object returned by an -objectForKey call on an NSDictionary object.

I'm currently working through the Ribbit app, on the "Saving the Media" video. I have created an NSString property to hold a captured video's file path, aptly named videoFilePath.

When I use the code:

        self.videoFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];

I receive a compiler error about ARC casting rules. Apparently Xcode believes calling "path" on the return value from the objectForKey call will return a CGPathRef object, because it thinks "path" is a property of a "CAAnimation" object, whatever that is.

Some Googling has led me to typecasting, so I've gone ahead and used:

        self.videoFilePath = [(NSURL *)[info objectForKey:UIImagePickerControllerMediaURL] path];

instead. But I've read in a few places that using typecasting like this is bad practice or "unsafe".

Since the return type of objectForKey is "id", this has led me to a question that I can't seem to find an answer to anywhere else. If different objects have different methods, but those methods may share the same name, either because they overwrite an inherited method or just reuse the name by coincidence, how does Xcode know which class's "path" method is being called for a return value of type "id"? And why does it think (unless I'm doing something very wrong here, incorrectly) that the returned value here is going to be of the "CAAnimate" class?

Thanks for reading this long post, and thanks for answering if you do!

4 Answers

Amit Bijlani
STAFF
Amit Bijlani
Treehouse Guest Teacher

Not sure where you heard that but typecasting is a good practice. It instructs your compiler to know which class to expect so that there are no ambiguities.

Colin Jackson
Colin Jackson
4,829 Points

Thanks for your response! Would you recommend always typecasting NSDictionary -objectForKey returns when we know the return type, then?

Amit Bijlani
Amit Bijlani
Treehouse Guest Teacher

Anytime the return type is id you should be typecasting if the variable you are assigning to is of a specific class.

Stone Preston
Stone Preston
42,016 Points

I just worked on this yesterday and was forced to do the same cast you did. Im doing this project a second time around with iOS7 and Xcode 5. I did not have this problem the first time around so it must be a change in the versions that causes this.

Colin Jackson
Colin Jackson
4,829 Points

Good to see someone else had this problem. Nothing at all about it on Google. I thought I was going crazy!

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

What worked at the time of recording no longer works in iOS 7. :( We discussed this in the Forum a while back. Glad you got the typecast solution!

Stone Preston
Stone Preston
42,016 Points

actually I just noticed that I did not use the same cast you did. I casted it to a NString object, not NSURL

Colin Jackson
Colin Jackson
4,829 Points

Oh, you probably casted the entire term (i.e. (NSString *)[[info objectForKey:UIImagePickerControllerMediaURL] path]), whereas I casted the return value, and then called path on it (see above).