Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa Webkit bug?

I have some code that gets the URL from an array and stores it as a string then uses that string to load up the URL.

NSString *first = [urls objectAtIndex:[sender clickedRow]];
NSLog(@"%@", first);
[[webview mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:first]]];

However, when I run this I get this error:

-[NSURL length]: unrecognized selector sent to instance 0x164dc0

The link in this case is http://www.digg.com

I know that the bug is in the line

NSString *first = [urls objectAtIndex:[sender clickedRow]];

because I tried setting the string's value directly to the URL instead of the array and it worked.

like image 777
Matt S. Avatar asked Nov 28 '22 04:11

Matt S.


1 Answers

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:

  1. Restore truth to the declaration, by declaring the variable as NSURL *, not NSString *.
  2. Don't attempt to create an NSURL here, because you already have one.
like image 111
Peter Hosey Avatar answered Dec 09 '22 17:12

Peter Hosey