Re: A Challenge WAS Accessor method idioms...
Re: A Challenge WAS Accessor method idioms...
- Subject: Re: A Challenge WAS Accessor method idioms...
- From: Ondra Cada <email@hidden>
- Date: Fri, 25 Mar 2005 17:17:40 +0100
Mike,
On 25.3.2005, at 16:35, Mike Ferris wrote:
Of curse, I still want the accessors declared in my header and
documented. And, of course, then the compiler's gonna whine about my
"incomplete" class...
This small problem can be cured if they are declared (and documented)
in a category (without an implementation of course), can't it? :) Or
perhaps even a formal protocol, which would bring one advantage of
having the method signatures ready -- see my (very simple and dumb)
code below...
Matter of fact, accessors being a special bunch of methods anyway, it
might be even beneficial making the whole interface more organised...
perhaps :)
'Course I can see some potential problems with naming of them
protocols, but I guess a few plain macros may be designed to cure them
perhaps :)
instead of having reams of accessor messages you just have a static
table at the top of the class definition describing each of the
instance variables to which you wish to offer access and how the user
gets to access them (e.g. by value, by copy, array manipulation etc.)
Done right, I'm afraid the example is not trivially typed into an
email message. ;-) This would be a significant mechanism, although
one that could be shared by any classes that wished to make use of it.
Anyway I *think* a q&d proof-of-concept implementation (ie., not "done
right", but showing how it would work and allowing some tests) might be
done comparatively easily using just heavy forwarding.
Conceptually, it may be perhaps similar to this code -- it is not quite
what we need (it's just my own *VERY DUMB* implementation of a
protocol-driven KVC which I've tried as my own proof-of-concept
four-odd years ago), but can be changed into what we do need, I think,
easily enough :) Alas I don't have the time the very now to do that
myself :(
// interface
@protocol OCSAccessorMethods // here the accessors are actually defined
(and, if need be, documented as well)
...
@end
// implementation
static NSProtocolChecker *checker;
@implementation NSMutableDictionary (OCSNamedAccess) // Instead of my
q&d dictionaries, KVC would be used of course
-(NSMethodSignature*)methodSignatureForSelector:(SEL)sel {
if (!checker)
checker=[[NSProtocolChecker alloc] initWithTarget:nil
protocol:@protocol(OCSAccessorMethods)];
return [checker methodSignatureForSelector:sel];
}
-(void)forwardInvocation:(NSInvocation*)inv {
NSMethodSignature *sig=[inv methodSignature];
NSString *message=NSStringFromSelector([inv selector]);
static NSCharacterSet *upper=nil;
if (!upper) upper=[[NSCharacterSet uppercaseLetterCharacterSet]
retain];
if ([sig numberOfArguments]==2) { // presumably a plain getter
id val=[self objectForKey:message];
switch ([sig methodReturnType][0]) {
int intval; double doubleval;
case '@':
[inv setReturnValue:&val];
return;
case 'i': case 'c': case 'I':
intval=[val intValue];
[inv setReturnValue:&intval];
return;
case 'd':
doubleval=[val doubleValue];
[inv setReturnValue:&doubleval];
return;
}
}
if ([message hasPrefix:@"set"] && [upper characterIsMember:[message
characterAtIndex:3]] && [sig numberOfArguments]==3) {
id idval; int intval; double doubleval;
message=[[[message substringWithRange:NSMakeRange(3,1)]
lowercaseString] stringByAppendingString:[message
substringWithRange:NSMakeRange(4,[message length]-5)]];
switch ([sig getArgumentTypeAtIndex:2][0]) {
case '@':
[inv getArgument:&idval atIndex:2];
if (!idval || ([idval isKindOfClass:[NSString class]]
&& [idval length]==0))
[self removeObjectForKey:message];
else [self setObject:idval forKey:message];
return;
case 'i': case 'c': case 'I':
[inv getArgument:&intval atIndex:2];
[self setObject:[NSNumber numberWithInt:intval]
forKey:message];
return;
case 'd':
[inv getArgument:&doubleval atIndex:2];
[self setObject:[NSNumber numberWithDouble:doubleval]
forKey:message];
return;
}
}
// got here: something's rotten
[self doesNotRecognizeSelector:[inv selector]];
}
@end
Of course, if it proves reasonable concept, the real-life
implementation would become pretty complicated (swizzling ISAs or doing
some similar hackery probably to be efficient enough).
---
Ondra Čada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden