A: 

your error message isn't being displayed but I'm assuming you've run into a statement which behind the scenes is calling isEqualToString and one of the objects isn't a string

klyde
+1  A: 

The error is not in the definition of the Joke class, but somewhere it's being used. In most cases with errors like this, it's the result of a memory management error — some object (presumably a string) gets deallocated and another gets allocated in its old memory location. Try running with NSZombieEnabled and see if it turns up a message to a dealloced object.

Chuck
This turned out not to be the case here, but I'm leaving it for Google purposes, because it is often the problem in cases like this.
Chuck
+2  A: 

You're shadowing a ivar name with the function argument. Try changing your jokeWithValue: method to this:

In joke.h:

+ (id)jokeWithValue:(NSString *)aJoke;

in joke.m:

+ (id)jokeWithValue:(NSString *)aJoke {
     Joke *j = [[Joke alloc] init];
     j.joke = aJoke;
     return [j autorelease];
}

Notice that the NSString variable name has changed so it no longer shadows the iVar joke.

EDIT:

On seeing how joke is called, it looks as if you're assigning a joke object to cell.text, which I believe is expecting an NSString not a joke.

try setting:

cell.text = [[jokes objectAtIndex:index] joke];

in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Grant Limberg
I will be surprised if this turns out to be the problem. He doesn't use the ivar in that method, so it should be safe (if not exactly good practice) to shadow it.
Chuck
This wouldn't actually cause his exception as they're both actually NSStrings though. He's probably comparing a Joke object to it's string value joke somewhere.
Jason Coco
Still not working. Same Errors
Daniel Kindler
+10  A: 

Replace this line:

cell.text = [jokes objectAtIndex:indexPath.row];

with these lines:

Joke *j = (Joke *)[jokes objectAtIndex:indexPath.row];
if( j )
  cell.text = j.joke;
Jason Coco
AHH IT WORKS! THANKS SO MUCH!
Daniel Kindler
Yeah, this works because cell.text expects a string, not a joke object. Before, cell.text's accessor was comparing the object you gave it (a Joke) to the object it had already (an NSString) and that's why you were seeing that exception. Another way you could have fixed this was to add an implementation of isEqualToString: on your Joke object and forward that request to your joke property.
Jason Coco
makes sense! Thanks so much man
Daniel Kindler
+3  A: 

The stack trace will help you find exactly what is calling isEqualToString:. Unfortunately, it's not giving you any symbols, so you'll have to do a little digging.

In Objective-C methods, there are two hidden parameters which are always passed as the first two arguments: self, a pointer to the object to which the message is being sent, and _cmd, a pointer to a C string containing the name of the message being sent. Examining the _cmd arguments in the stack frames will help you debug the problem.

The first thing you want to do is set a breakpoint right before the exception is thrown. Open up the debugger console (Cmd+Shift+R) and add a breakpoint to the function on the top of the stack trace by typing:

break 2438463755

Now run your app, and the debugger should break right before throwing the exception. It should also give you a full symbolic backtrace; if not, you'll have to walk the stack yourself. You can walk the stack and print out the value of the various _cmd parameters.

Adam Rosenfield