BOOL returned via -performSelctor: not BOOL on 64-bit system
BOOL returned via -performSelctor: not BOOL on 64-bit system
- Subject: BOOL returned via -performSelctor: not BOOL on 64-bit system
- From: James Bucanek <email@hidden>
- Date: Tue, 8 Jun 2010 09:16:08 -0700
Greetings,
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)
The selector identifies a method that returns a BOOL, but
sometimes the value returned by -performSelector contains odd
data. I added some code to log the value (as an integer)
returned by [condition performSelector:conditionSelector]; Most
of the time it's 0 or 1, but sometimes it's 0x5400 or 0x2300
when the method returned NO. Note that I cannot reproduce this
on the two 64-bit Intel systems I have, even though one of them
is the same model of MacPro with the same dual-Quad-Core Intel
Xeon as my customer's. All are running 10.6.3.
I thought that, in Objective-C, all pointer and integer scalar
values were interchangeable in the return value of a method. Is
this a bug in GCC, a bug in the Objective-C runtime, did this
rule change in the 64-bit world, or is there possibly something
strange about this particular user's system?
Anyway, I'm considering changing my code to read 'if
(([condition performSelector:conditionSelector]&0x1)!=NO)' to
work around this issue, but I'd like to get a fuller
understanding of the problem for future reference (and so I
don't say something stupid in my next book about Objective-C!).
--- code snippets ---
@implementation ActionCondition
...
- (BOOL)test
{
// subclass overrides this method to test some condition
return ( ... );
}
...
- (BOOL)shouldCancelAction
{
// if this condition causes actions to be skipped, apply
the condition
return ( [self canCancelAction] ? [self test] : NO );
}
- (BOOL)shouldHoldAction
{
// if this condition causes actions to be held, apply the condition
return ( [self canHoldAction] ? [self test] : NO );
}
- (BOOL)shouldStopAction
{
// If this condition causes actions to abort, apply the condition
return ( [self canStopAction] ? [self test] : NO );
}
@end
@implementation ActionItem
...
static ActionCondition* FindCondition( NSArray* conditions, SEL
conditionSelector )
{
// Returns first ActionCondition that returns YES from the
given condition message
NSEnumerator* e = [conditions objectEnumerator];
ActionCondition* condition;
while ( (condition=[e nextObject]) != nil )
{
if ([condition performSelector:conditionSelector]!=NO)
<------- sometimes returns something other than 0 or 1
return (condition);
}
return (nil);
}
- (ActionCondition*)cancelCondition
{
return (FindCondition([self conditions],@selector(shouldCancelAction)));
}
- (ActionCondition*)holdCondition
{
return (FindCondition([self conditions],@selector(shouldHoldAction)));
}
- (ActionCondition*)stopCondition
{
return (FindCondition([self conditions],@selector(shouldStopAction)));
}
@end
--
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