Ada*_*amG 3 objective-c ios facebook-sdk-3.0
在Facebook iOS SDK中,使用以下处理程序返回请求:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) { }
Run Code Online (Sandbox Code Playgroud)
然后可以使用这些调用来访问用户变量......
self.userNameLabel.text = user.name;
self.userProfileImage.profileID = user.id;
Run Code Online (Sandbox Code Playgroud)
这种语法有点类似于id <protocolDelegate> object公共属性声明的语法语法,除了NSDictionary是明确的id对象,并且该字典符合协议?但点语法来自何处以及如何声明任意NSFoundation对象与协议相对应而没有对对象本身进行子类化并使其符合?
我做了一些关于点符号和NSDictionary的额外研究,看起来如果没有在NSDictionary中添加类别,就不可能在字典上使用点符号.但是,我没有在Apple文档中看到任何<>语法的引用,表明NSDictionary的这个特定实例符合该表示法.
关于这种包装的工作方式,Facebook文档有点稀疏:
FBGraphUser协议表示Facebook用户对象最常用的属性.它可用于访问已使用FBGraphObject外观包装的NSDictionary对象.
如果跟随这个引导到FBGraphObject文档,那么有一些方法返回符合这个"外观......"的字典,但没有关于如何包装字典的进一步解释.
所以我想我的问题有几点:
任何解释或见解将非常感谢!
基本上,NSDictionary<FBGraphUser> *user意味着一个继承自的对象NSDictionary,添加FBGraphUser协议声明的功能(特别是类型化访问).
这种方法背后的原因在FBGraphObject文档中详细描述(FBGraphUser协议扩展了FBGraphObject协议).你可能会感到困惑的是,这FBGraphObject是一个协议(在这里描述)和一个继承自的类(在这里描述)NSMutableDictionary.
在内部实现方面,它是一些非常先进的Objective-C动态魔法,你可能不想担心.您需要知道的是,如果您愿意,可以将对象视为字典,或者使用协议中的其他方法.如果您真的想知道详细信息,可以查看FBGraphObject的源代码,特别是这些方法:
#pragma mark -
#pragma mark NSObject overrides
// make the respondsToSelector method do the right thing for the selectors we handle
- (BOOL)respondsToSelector:(SEL)sel
{
return [super respondsToSelector:sel] ||
([FBGraphObject inferredImplTypeForSelector:sel] != SelectorInferredImplTypeNone);
}
- (BOOL)conformsToProtocol:(Protocol *)protocol {
return [super conformsToProtocol:protocol] ||
([FBGraphObject isProtocolImplementationInferable:protocol
checkFBGraphObjectAdoption:YES]);
}
// returns the signature for the method that we will actually invoke
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
SEL alternateSelector = sel;
// if we should forward, to where?
switch ([FBGraphObject inferredImplTypeForSelector:sel]) {
case SelectorInferredImplTypeGet:
alternateSelector = @selector(objectForKey:);
break;
case SelectorInferredImplTypeSet:
alternateSelector = @selector(setObject:forKey:);
break;
case SelectorInferredImplTypeNone:
default:
break;
}
return [super methodSignatureForSelector:alternateSelector];
}
// forwards otherwise missing selectors that match the FBGraphObject convention
- (void)forwardInvocation:(NSInvocation *)invocation {
// if we should forward, to where?
switch ([FBGraphObject inferredImplTypeForSelector:[invocation selector]]) {
case SelectorInferredImplTypeGet: {
// property getter impl uses the selector name as an argument...
NSString *propertyName = NSStringFromSelector([invocation selector]);
[invocation setArgument:&propertyName atIndex:2];
//... to the replacement method objectForKey:
invocation.selector = @selector(objectForKey:);
[invocation invokeWithTarget:self];
break;
}
case SelectorInferredImplTypeSet: {
// property setter impl uses the selector name as an argument...
NSMutableString *propertyName = [NSMutableString stringWithString:NSStringFromSelector([invocation selector])];
// remove 'set' and trailing ':', and lowercase the new first character
[propertyName deleteCharactersInRange:NSMakeRange(0, 3)]; // "set"
[propertyName deleteCharactersInRange:NSMakeRange(propertyName.length - 1, 1)]; // ":"
NSString *firstChar = [[propertyName substringWithRange:NSMakeRange(0,1)] lowercaseString];
[propertyName replaceCharactersInRange:NSMakeRange(0, 1) withString:firstChar];
// the object argument is already in the right place (2), but we need to set the key argument
[invocation setArgument:&propertyName atIndex:3];
// and replace the missing method with setObject:forKey:
invocation.selector = @selector(setObject:forKey:);
[invocation invokeWithTarget:self];
break;
}
case SelectorInferredImplTypeNone:
default:
[super forwardInvocation:invocation];
return;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3285 次 |
| 最近记录: |