Re: BOOL returned via -performSelctor: not BOOL on 64-bit system
Re: BOOL returned via -performSelctor: not BOOL on 64-bit system
- Subject: Re: BOOL returned via -performSelctor: not BOOL on 64-bit system
- From: James Bucanek <email@hidden>
- Date: Tue, 8 Jun 2010 10:23:57 -0700
Nick Zitzmann <mailto:email@hidden> wrote (Tuesday, June
8, 2010 9:27 AM -0600):
On Jun 8, 2010, at 10:16 AM, James Bucanek wrote:
I've been trying to track down a peculiar bug reported by a customer, and I've narrowed it down to a problem returning a BOOL value via
-[NSObject performSelector:] on a dual Quad-Core Intel Xeon
processor running 64-bit code. It seems that the returned value
contains random data, which obscures the BOOL.
I've included the relevant code from the project below for completeness, but the problem boils down to this statement:
if ([condition performSelector:conditionSelector]!=NO)
According to the documentation, that method returns an object,
not a primitive. You can't use it if the selector returns a
primitive; it doesn't work that way. If you want to call some
selector and get a BOOL return value, then you must do this instead:
BOOL returnValue = ((BOOL (*)(id, SEL))objc_msgSend)(condition, conditionSelector);
For the record, the following is equivalent (i.e. produces the
same machine code) and is probably a little easier to read:
BOOL returnValue = (BOOL)((uintptr_t)[condition performSelector:conditionSelector]);
This, incidentally, works for all primitives except for some floating point
primitives, where you may have to use objc_msgSend_fpret() instead depending
on the rules of your architecture.
Thanks for getting me back on track. I see now that the BOOL
return value is just fine--as long as you convince the compiler
to only pay attention to the BOOL (char) part of the return
value. Casting the return as a BOOL type and/or assigning it to
a BOOL value is sufficient to avoid any detritus.
I thought that, in Objective-C, all pointer and integer scalar values were
interchangeable in the return value of a method.
You thought wrong.
Thanks. I think. :/
I realize now that I was thinking about the rules for nil
objects; objc_msgSend guarantees that the value returned when
sending to a nil object is compatible with all pointer, floating
point, and integer scalar return values. But this clearly can't
be extrapolated to the general case of -performSelector:.
--
James Bucanek
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden