ios - NSDictionary<FBGraphUser> *user syntax explanation -


in facebook ios sdk requests returned following handler:

 ^(fbrequestconnection *connection,         nsdictionary<fbgraphuser> *user,         nserror *error) { } 

the user variable can accessed calls these...

   self.usernamelabel.text = user.name;    self.userprofileimage.profileid = user.id; 

this syntax similar syntax id <protocoldelegate> object syntax common property declaration, except nsdictionary id object explicitely, , dictionary conforms protocol? dot syntax come , how 1 state arbitrary nsfoundation object corresponds protocol without subclassing object , making conform?

i did additional research dot notation , nsdictionary , appears not possible use dot notation on dictionary without adding category nsdictionary. however, did not see reference of <> syntax in apple documentation indicate particular instance of nsdictionary conformed notation.

and facebook documentation little sparse on how wrapping works:

the fbgraphuser protocol represents commonly used properties of facebook user object. may used access nsdictionary object has been wrapped fbgraphobject facade.

if 1 follows lead fbgraphobject documentation there methods return dictionaries conform "facade..." no further explanation on how 1 goes wrapping dictionary.

so guess questions few:

  1. what underlying code make sort of syntax work?
  2. why exist?
  3. why facebook implement way opposed making object can convert data into?

any explanation or insight appreciated!

basically, nsdictionary<fbgraphuser> *user, implies object inherits nsdictionary, adding functionality (specifically, typed access) declared fbgraphuser protocol.

the reasons behind approach described in quite bit of detail in fbgraphobject documentation (the fbgraphuser protocol extends fbgraphobject protocol). might confusing fbgraphobject protocol (described here) , class (described here), inherits nsmutabledictionary.

in terms of inner implementation, it's pretty advanced objective-c dynamic magic, don't want worry about. need know can treat object dictionary if wish, or use additional methods in protocol. if want know details, can @ source code fbgraphobject, in particular, these methods:

#pragma mark - #pragma mark nsobject overrides  // make respondstoselector method right thing selectors 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 signature method invoke - (nsmethodsignature *)methodsignatureforselector:(sel)sel {     sel alternateselector = sel;      // if should forward, 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 match fbgraphobject convention - (void)forwardinvocation:(nsinvocation *)invocation {     // if should forward, where?     switch ([fbgraphobject inferredimpltypeforselector:[invocation selector]]) {         case selectorinferredimpltypeget: {             // property getter impl uses selector name argument...             nsstring *propertyname = nsstringfromselector([invocation selector]);             [invocation setargument:&propertyname atindex:2];             //... replacement method objectforkey:             invocation.selector = @selector(objectforkey:);             [invocation invokewithtarget:self];             break;         }         case selectorinferredimpltypeset: {             // property setter impl uses selector name argument...             nsmutablestring *propertyname = [nsmutablestring stringwithstring:nsstringfromselector([invocation selector])];             // remove 'set' , trailing ':', , lowercase 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];             // object argument in right place (2), need set key argument             [invocation setargument:&propertyname atindex:3];             // , replace missing method setobject:forkey:             invocation.selector = @selector(setobject:forkey:);             [invocation invokewithtarget:self];              break;         }          case selectorinferredimpltypenone:         default:              [super forwardinvocation:invocation];             return;     } } 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -