views:

69

answers:

2

The following will compile but if run it will crash.

-(void) testFunc : (NSString *)s{
    NSLog(@"%@", s);
}

What's wrong with this code?

I call the function like this:

NSString *msg = @"This is a message";
[self performSelector:@selector(testFunc) withObject:msg afterDelay:0];
[msg release];
+1  A: 

Are you sure s is a valid pointer to an NSString?

icktoofay
I edited the original message to show how s is declared.
awakeFromNib
awakeFromNib: That doesn't answer icktoofay's question. Declaring the variable correctly has no bearing on the validity of the pointer you put in that variable. An invalidly-declared variable will simply fail compilation, whereas a bogus pointer in that variable will cause a crash when you try to send a message to the object at the bogus pointer.
Peter Hosey
I wouldn't know if it's a valid pointer so I just posted what I wrote.
awakeFromNib
awakeFromNib: icktoofay's question was rhetorical—a cue for you to investigate further, and a suggestion of a line along which to do so. The way to investigate that would have been to run your app under the Zombies instrument and see whether the object that had been pointed to by the `s` variable got prematurely released. (That wouldn't cause an exception upon sending *yourself* a message, though.)
Peter Hosey
+6  A: 
[self performSelector:@selector(testFunc) withObject:msg afterDelay:0];

Should be:

[self performSelector:@selector(testFunc:) withObject:msg afterDelay:0];
Jacob Relkin
Is that because it takes one argument? What if it took two?
awakeFromNib
Yes, if it takes one argument, the selector would merely need a `:` appended. For more than one, you'd need to use the argument's name and another `:`.
Jacob Relkin
In other words, the selector has one : per argument the method takes. A method that takes no argument has merely a single segment in its selector with no colon; a method that takes one argument has a single segment followed by a colon; a method that takes multiple arguments has as many segments, each and every one followed by a colon. Thus, the selector you used in the code in your question would reach a method named `testFunc` (taking no arguments); since you have no such method, the code causes an exception instead. Because the method you have takes one argument, its selector is `testFunc:`.
Peter Hosey
@Peter exactly.
Jacob Relkin