Skip to content
This repository has been archived by the owner on Dec 26, 2018. It is now read-only.

Commit

Permalink
Clean up methods in A2BlockDelegate. Support BlocksKit selector.
Browse files Browse the repository at this point in the history
Signed-off-by: Zachary Waldowski <zwaldowski@gmail.com>
  • Loading branch information
zwaldowski committed Mar 31, 2012
1 parent ff1aee8 commit c4971cb
Showing 1 changed file with 3 additions and 71 deletions.
74 changes: 3 additions & 71 deletions A2BlockDelegate.m
Expand Up @@ -33,7 +33,7 @@

@interface NSObject (A2BlockDelegatePrivate)

+ (BOOL) a2_getProtocol: (Protocol **) _protocol representedSelector: (SEL *) _representedSelector forPropertyAccessor: (SEL) selector __attribute__((nonnull));
- (void) a2_checkRegisteredProtocol:(Protocol *)protocol;

+ (NSDictionary *) a2_mapForProtocol: (Protocol *) protocol;

Expand All @@ -57,76 +57,6 @@ @implementation NSObject (A2BlockDelegate)

#pragma mark Helpers

+ (BOOL) a2_getProtocol: (Protocol **) _protocol representedSelector: (SEL *) _representedSelector forPropertyAccessor: (SEL) selector
{
__block BOOL found = NO;

[[self a2_protocols] enumerateObjectsUsingBlock: ^(Protocol *protocol, BOOL *stop) {
NSString *representedName = [[self a2_selectorCacheForProtocol: protocol] objectForKey: NSStringFromSelector(selector)];

if (representedName)
{
*_representedSelector = NSSelectorFromString(representedName);
*_protocol = protocol;
found = *stop = YES;
}
}];

if (found) return YES;

NSString *propertyName = NSStringFromSelector(selector);
if ([propertyName hasPrefix: @"set"])
{
unichar firstChar = [propertyName characterAtIndex: 3];
NSString *coda = [propertyName substringWithRange: NSMakeRange(4, propertyName.length - 5)]; // -5 to remove trailing ':'
propertyName = [NSString stringWithFormat: @"%c%@", tolower(firstChar), coda];
}

if (!class_getProperty(self, propertyName.UTF8String))
{
// It's not a simple -xBlock/setXBlock: pair

// If selector ends in ':', it's a setter.
const BOOL isSetter = [NSStringFromSelector(selector) hasSuffix: @":"];
const char *key = (isSetter ? "S" : "G");

unsigned int i, count;
objc_property_t *properties = class_copyPropertyList(self, &count);

for (i = 0; i < count; ++i)
{
objc_property_t property = properties[i];

char *accessorName = a2_property_copyAttributeValue(property, key);
SEL accessor = sel_getUid(accessorName);
if (sel_isEqual(selector, accessor))
{
propertyName = [NSString stringWithUTF8String: property_getName(property)];
break; // from for-loop
}

free(accessorName);
}

free(properties);
}

if (!propertyName) return NO;

[[self a2_protocols] enumerateObjectsUsingBlock: ^(Protocol *protocol, BOOL *stop) {
NSString *selectorName = [[self a2_propertyMapForProtocol: protocol] objectForKey: propertyName];
if (!selectorName) return;

[[self a2_selectorCacheForProtocol: protocol] setObject: selectorName forKey: NSStringFromSelector(selector)];

*_representedSelector = NSSelectorFromString(selectorName);
*_protocol = protocol;
found = *stop = YES;
}];

return found;
}

+ (NSDictionary *) a2_mapForProtocol: (Protocol *) protocol
{
[[self a2_protocols] addObject: protocol];
Expand Down Expand Up @@ -232,6 +162,8 @@ + (void) linkProtocol: (Protocol *) protocol methods: (NSDictionary *) dictionar

SEL setter = a2_setterForProperty(self, propertyName);
IMP setterImplementation = pl_imp_implementationWithBlock(^(NSObject *obj, id block) {
if ([obj respondsToSelector:@selector(a2_checkRegisteredProtocol:)])
[obj performSelector:@selector(a2_checkRegisteredProtocol:) withObject:protocol];
[[obj dynamicDelegateForProtocol: protocol] implementMethod: representedSelector withBlock: block];
});
const char *setterTypes = "v@:@";
Expand Down

0 comments on commit c4971cb

Please sign in to comment.