Skip to content

Commit

Permalink
Merge pull request #81 from ryanolsonk/multiComponentKeyPathFix
Browse files Browse the repository at this point in the history
Fix view hierarchy debugging with complex key paths
  • Loading branch information
wlue committed Jan 2, 2014
2 parents 6677f33 + 42a28bb commit 8c950ae
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions ObjC/PonyDebugger/PDDOMDomainController.m
Original file line number Diff line number Diff line change
Expand Up @@ -783,10 +783,33 @@ - (NSString *)stringForValue:(id)value atKeyPath:(NSString *)keyPath onObject:(i
- (const char *)typeEncodingForKeyPath:(NSString *)keyPath onObject:(id)object;
{
const char *encoding = NULL;
NSString *lastKeyPathComponent = nil;
id targetObject = nil;

// Separate the key path components
NSArray *keyPathComponents = [keyPath componentsSeparatedByString:@"."];

if ([keyPathComponents count] > 1) {
// Drill down to find the targetObject.key piece that we're interested in.
NSMutableArray *mutableComponents = [keyPathComponents mutableCopy];
lastKeyPathComponent = [mutableComponents lastObject];
[mutableComponents removeLastObject];

NSString *targetKeyPath = [mutableComponents componentsJoinedByString:@"."];
@try {
targetObject = [object valueForKeyPath:targetKeyPath];
} @catch (NSException *exception) {
// Silently fail for KVC non-compliance
}
} else {
// This is the simple case with no dots. Use the full key and original target object
lastKeyPathComponent = keyPath;
targetObject = object;
}

// Look for a matching set* method to infer the type
NSString *selectorString = [NSString stringWithFormat:@"set%@:", [keyPath stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[keyPath substringToIndex:1] uppercaseString]]];
NSMethodSignature *methodSignature = [object methodSignatureForSelector:NSSelectorFromString(selectorString)];
NSString *selectorString = [NSString stringWithFormat:@"set%@:", [lastKeyPathComponent stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[lastKeyPathComponent substringToIndex:1] uppercaseString]]];
NSMethodSignature *methodSignature = [targetObject methodSignatureForSelector:NSSelectorFromString(selectorString)];
if (methodSignature) {
// We don't care about arg0 (self) or arg1 (_cmd)
encoding = [methodSignature getArgumentTypeAtIndex:2];
Expand All @@ -795,7 +818,7 @@ - (const char *)typeEncodingForKeyPath:(NSString *)keyPath onObject:(id)object;
// If we didn't find a setter, look for the getter
// We could be more exhasutive here with KVC conventions, but these two will cover the majority of cases
if (!encoding) {
NSMethodSignature *getterSignature = [object methodSignatureForSelector:NSSelectorFromString(keyPath)];
NSMethodSignature *getterSignature = [targetObject methodSignatureForSelector:NSSelectorFromString(lastKeyPathComponent)];
encoding = [getterSignature methodReturnType];
}

Expand Down

0 comments on commit 8c950ae

Please sign in to comment.