Francesco
Francesco

Reputation: 1047

Arguments and selectors

Is this:

[self showInWindow:window];

what get called after delay by this code:

[self performSelector:@selector(showInWindow:)
           withObject:window
           afterDelay:delay];

or am I misunderstanding the method?

Edit: the problem I'm having is that the method showInWindow get called after the delay but behaves like [self showInWindow:nil]. Any suggestion?

Upvotes: 1

Views: 82

Answers (2)

abarnert
abarnert

Reputation: 365627

Yes, that's what gets called. (After the delay, of course.)

The documentation doesn't really explain what it means to "perform the selector", but what it means is exactly what you suspect.

There is one small difference between using performSelector:withObject: type methods and sending the message directly: they only work if the object is actually an object (that is, an id, a pointer to an Objective C object). But window obviously is an object.

(Strictly speaking, this isn't quite true. If you pass something that's the same size as an id or smaller, it will often work. In some cases it won't. In some cases it will work, but is illegal. In some cases, it will work and is legal but Apple strongly recommends against it. There are no cases where it's a good idea—so instead of learning the specific rules, just assume it never works. The only reason to bring this up is that this used to be common practice in Objective C back in the NeXT days, so you may occasionally still see it in other people's today.)

For more information about the performSelector: family, see the NSObject Protocol Reference, and the SO question Using -performSelector: vs. just calling the method. (For information specifically about the afterDelay: variants, see the documentation linked above.)

From the later edit to the question:

the problem I'm having is that the method showInWindow get called after the delay but behaves like [self showInWindow:nil]. Any suggestion?

First, in what way does it "behave like" the parameter is nil? Is the parameter actually nil? (Just log it in the showInWindow: implementation; if you haven't overridden the base implementation, just add an override that logs and calls the base.)

Second, if it actually is nil, was it nil at the time you sent performSelector:withObject:afterDelay:? If so, obviously it'll still be nil when the selector is sent. Also, make sure window really is an id rather than some other type. (Note that if you've got members, properties, globals, and/or locals sharing the name window, it can be confusing which one you're referring to. This is a common source of problems.)

If it's actually not nil when you schedule it, but is nil when it arrives, there are a few ways that could happen, but they're all less likely, and trickier to debug, than these two cases, so let's rule them out first.

Upvotes: 2

mprivat
mprivat

Reputation: 21902

Yes, that's what it does... Although keep in mind that it may take longer than the delay to execute. This method basically sets up an NSTimer in the current thread's run loop, so if your thread gets busy doing heavy duty work and the run loop takes longer than your delay to come back, your method will get executed later.

Upvotes: 0

Related Questions