However, when I run this I get this error:
-[NSURL length]: unrecognized selector sent to instance 0x164dc0
First off, that's an exception, not an error.
When you get a message like this, read what it says:
-[NSURL
The object you sent this message to was an NSURL object.
length]:
The selector of the message was length
.
Now, why would you send a length
message to an NSURL object? You wouldn't, and you didn't do so yourself. Something else did.
But you would send a length
message to a string object. So, you have an NSURL object, and you passed it somewhere that expected a string.
There's only one passage in the code you showed:
[NSURL URLWithString:first]
The exception tells you that first
is already an NSURL; it is not a string. You do not need to create an NSURL from it, since it already is one, and trying to treat it as a string in any way will cause an exception.
You may be about to object to my claim on the grounds of this previous line:
NSString *first = [urls objectAtIndex:[sender clickedRow]];
Your objection would be that the declaration clearly says that first
is a pointer to an NSString, so I must be wrong.
But that is not so. You declared first
as a pointer to an NSString. That is to say, you told the compiler that the variable first
would hold a pointer to an NSString.
But then you put a pointer to an NSURL into the variable.
In many cases, the compiler would warn you that you have lied to it, but it didn't in this case because the object came through objectAtIndex:
, which returns id
; thus, the compiler doesn't know what type of object you're putting into the variable. The compiler, assuming that you told the truth and really are putting an NSString here, does not warn for this initialization.
But you're not. The object is an NSURL, as you found out at run time.
The fix is two-fold:
- Restore truth to the declaration, by declaring the variable as
NSURL *
, not NSString *
.
- Don't attempt to create an NSURL here, because you already have one.