FROM : Michael Ash
DATE : Tue Aug 01 01:09:47 2006
On 7/31/06, Tommy Nordgren <tommy.<email_removed>> wrote:
>
> This, to be extended with further methods:
> @implementation NSCoder (ConditionalCoding)
>
> -(void) encodeObject:(id) obj onCondition:(SEL) cond withOwner: (id)
> owner
> {
> BOOL strongCode = NO;
> NSMethodSignature * sign = [obj methodSignatureForSelector:cond];
> if (sign == nil) {
> strongCode = YES;
> } else {
> if ([sign numberOfArguments] == 3 &&
> strcmp([sign getArgumentTypeAtIndex:2],@encode(id)) == 0 &&
> strcmp([sign methodReturnType] , @encode(BOOL)) == 0) {
> int i = (int) objc_msgSend(obj,cond,owner);
> strongCode = i ? YES: NO;
> }
> }
> if ( strongCode) {
> [self encodeObject: obj];
> } else {
> [self encodeConditionalObject:obj];
> }
> }
> @end
Why bother with this type checking only to have it fail silently
anyway? Much better would be to simply add this to the header:
// cond must return a BOOL and take a single id argument
If you insist on a runtime check then you should throw an exception or
something similar if the method signature does not match. Simply
taking a wrong signature as NO is going to create annoying and
difficult-to-find errors.
I should also note that your call to objc_msgSend is faulty. BOOL is
one byte, but int is four and id is also four. By using a function
declared to return id and casting its return value to int, you risk
picking up junk in the return value and getting false positives.
Instead, call it like this:
((BOOL (*)(id, SEL, id))objc_msgSend)(obj, cond, owner)
Mike
DATE : Tue Aug 01 01:09:47 2006
On 7/31/06, Tommy Nordgren <tommy.<email_removed>> wrote:
>
> This, to be extended with further methods:
> @implementation NSCoder (ConditionalCoding)
>
> -(void) encodeObject:(id) obj onCondition:(SEL) cond withOwner: (id)
> owner
> {
> BOOL strongCode = NO;
> NSMethodSignature * sign = [obj methodSignatureForSelector:cond];
> if (sign == nil) {
> strongCode = YES;
> } else {
> if ([sign numberOfArguments] == 3 &&
> strcmp([sign getArgumentTypeAtIndex:2],@encode(id)) == 0 &&
> strcmp([sign methodReturnType] , @encode(BOOL)) == 0) {
> int i = (int) objc_msgSend(obj,cond,owner);
> strongCode = i ? YES: NO;
> }
> }
> if ( strongCode) {
> [self encodeObject: obj];
> } else {
> [self encodeConditionalObject:obj];
> }
> }
> @end
Why bother with this type checking only to have it fail silently
anyway? Much better would be to simply add this to the header:
// cond must return a BOOL and take a single id argument
If you insist on a runtime check then you should throw an exception or
something similar if the method signature does not match. Simply
taking a wrong signature as NO is going to create annoying and
difficult-to-find errors.
I should also note that your call to objc_msgSend is faulty. BOOL is
one byte, but int is four and id is also four. By using a function
declared to return id and casting its return value to int, you risk
picking up junk in the return value and getting false positives.
Instead, call it like this:
((BOOL (*)(id, SEL, id))objc_msgSend)(obj, cond, owner)
Mike
| Related mails | Author | Date |
|---|---|---|
| Tommy Nordgren | Jul 31, 20:23 | |
| Andrei Tchijov | Jul 31, 20:30 | |
| Ryan Britton | Jul 31, 20:32 | |
| Sherm Pendley | Jul 31, 20:39 | |
| Bill Bumgarner | Jul 31, 20:49 | |
| Tommy Nordgren | Jul 31, 21:31 | |
| Erik Buck | Jul 31, 23:19 | |
| Michael Ash | Aug 1, 01:09 |






Cocoa mail archive

