Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSDictionary<;FBGraphUser>*用户语法解释_Ios_Objective C_Facebook Sdk 3.0 - Fatal编程技术网

Ios NSDictionary<;FBGraphUser>*用户语法解释

Ios NSDictionary<;FBGraphUser>*用户语法解释,ios,objective-c,facebook-sdk-3.0,Ios,Objective C,Facebook Sdk 3.0,在Facebook iOS SDK中,将使用以下处理程序返回请求: ^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) { } 此语法与作为公共属性声明的语法id object语法有些相似,只是NSDictionary明确地是id对象,并且该字典符合协议?但是dot语法从何而来,如何声明任意NSFoundation对象与协议相对应,而

在Facebook iOS SDK中,将使用以下处理程序返回请求:

 ^(FBRequestConnection *connection, 
       NSDictionary<FBGraphUser> *user, 
       NSError *error) { }
此语法与作为公共属性声明的语法
id object
语法有些相似,只是NSDictionary明确地是id对象,并且该字典符合协议?但是dot语法从何而来,如何声明任意NSFoundation对象与协议相对应,而不将对象本身子类化并使其一致

我做了一些额外的研究,似乎不可能在字典中添加一个类别就在字典中使用点符号。但是,我在中没有看到任何语法参考,以表明NSDictionary的这个特定实例符合该符号

Facebook的文档中很少有关于这种包装的工作原理:

FBGraphUser协议代表最常用的属性 Facebook用户对象的。它可用于访问NSD字典 已用FBGraphObject外观包装的对象

如果按照这条线索找到FBGraphObject文档,那么有一些方法返回符合此“facade…”的词典,但没有进一步解释如何包装词典

所以我想我的问题是:

  • 底层代码是什么样子的 语法工作
  • 它为什么存在
  • 为什么facebook会以这种方式实施,而不仅仅是 制作一个他们可以将数据转换成的对象
  • 任何解释或见解都将不胜感激

    此语法与syntax id object语法有些相似

    “有些相似”?“一模一样”怎么样

    而且字典符合协议

    不,声明说您必须传入一个对象,该对象的类是
    NSDictionary
    ,同时它符合
    FBGraphUser
    协议

    但是点语法是从哪里来的呢

    我不明白。它来自于编写有问题代码的程序员。这是可能的,因为
    FBGraphUser
    协议声明了一些属性,然后可以通过点表示法访问这些属性

    如何声明任意NSFoundation对象与协议相对应,而不将对象本身子类化并使其符合

    这不是所谓的“NS粉底”,只是基础。它不是不“符合”协议的对象,而是它的类。你自己也展示了它的语法

    它是如何实施的?简单:一个类别

    #import <Foundation/Foundation.h>
    
    @protocol Foo
    @property (readonly, assign) int answer;
    @end
    
    @interface NSDictionary (MyCategory) <Foo>
    @end
    
    @implementation NSDictionary (MyCategory)
    
    - (int)answer
    {
        return 42;
    }
    
    @end
    
    int main()
    {
        NSDictionary *d = [NSDictionary dictionary];
        NSLog(@"%d", d.answer);
        return 0;
    }
    
    #导入
    @协议Foo
    @属性(只读,赋值)int-answer;
    @结束
    @接口字典(MyCategory)
    @结束
    @实现NSDictionary(MyCategory)
    -(int)答案
    {
    返回42;
    }
    @结束
    int main()
    {
    NSDictionary*d=[NSDictionary dictionary];
    NSLog(@“%d”,d.答案);
    返回0;
    }
    
    这是一个SSCCE,i。E它按原样编译和运行,试试看

    要使这种语法正常工作,底层代码是什么样子的

    上面回答

    它为什么存在

    因为语言是这样定义的

    facebook为什么要以这种方式实现它,而不是仅仅制作一个他们可以将数据转换成的对象


    我不知道,问问Facebook的家伙。

    基本上,
    NSDictionary*user
    ,意味着一个对象继承自
    NSDictionary
    ,添加了
    FBGraphUser
    协议声明的功能(特别是键入访问)

    这种方法背后的原因在中有相当详细的描述(
    FBGraphUser
    协议扩展了
    FBGraphObject
    协议)。可能让您感到困惑的是,
    FBGraphObject
    是一个协议(已描述)和一个类(已描述),它继承自
    NSMutableDictionary

    就内部实现而言,这是一些非常高级的Objective-C动态魔法,您可能不想担心。您需要知道的是,如果愿意,您可以将该对象视为字典,或者使用协议中的其他方法。如果您确实想了解详细信息,可以查看以下方法,尤其是:

    #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;
        }
    }
    

    jbat100我可以在Facebook SDK范围之外的其他方式中使用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;
        }
    }