On Jun 8, 2010, at 1:37 PM, Jean-Daniel Dupas wrote:
> 
> Le 8 juin 2010 à 19:23, James Bucanek a écrit :
> 
>> Nick Zitzmann <mailto:n...@chronosnet.com> 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]);
> 
> It's not more valid though. -performSelector must be used only with selector 
> that return an object.
> 
> From the -performSelector reference:
> 
> "For methods that return anything other than an object, use NSInvocation."

Alternatively, if you can alter the method being called, (which I assume you 
can, since you posted the source) you could change the methods to return an 
NSNumber-wrapped boolean value, rather than a scalar value. 
(Standard "written-in-Mail" warning applies)

> - (NSNumber*)shouldCancelAction
> {
>   // if this condition causes actions to be skipped, apply the condition
>   return [NSNumber numberWithBool:( [self canCancelAction] ? [self test] : NO 
> )];
> }
> 
> - (NSNumber*)shouldHoldAction
> {
>   // if this condition causes actions to be held, apply the condition
>   return [NSNumber numberWithBool:( [self canHoldAction] ? [self test] : NO 
> )];
> }
> 
> - (NSNumber*)shouldStopAction
> {
>   // If this condition causes actions to abort, apply the condition
>   return [NSNumber numberWithBool:( [self canStopAction] ? [self test] : NO 
> )];
> }

And the conditional statements change to the form:

> if (![[condition performSelector:conditionSelector] boolValue])

This is certainly the least performant of the recommended solutions, but if 
that's not a major concern, this would be my preferred way, since I think it's 
the easiest to read.

- Alex_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to