react-native-navigation的迁移库

RNNOptions.m 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #import "RNNOptions.h"
  2. #import <objc/runtime.h>
  3. @implementation RNNOptions
  4. -(instancetype) initWithDict:(NSDictionary *)dict {
  5. self = [super init];
  6. [self initializeOptionsPropertiesWithDict:dict];
  7. [self mergeWith:dict];
  8. return self;
  9. }
  10. - (void)applyOn:(UIViewController *)viewController defaultOptions:(RNNOptions *)defaultOptions {
  11. [defaultOptions applyOn:viewController];
  12. [self applyOn:viewController];
  13. }
  14. -(void)mergeWith:(NSDictionary *)otherOptions {
  15. for (id key in otherOptions) {
  16. if ([self hasProperty:key]) {
  17. if ([[self valueForKey:key] isKindOfClass:[RNNOptions class]]) {
  18. RNNOptions* options = [self valueForKey:key];
  19. [options mergeWith:[otherOptions objectForKey:key]];
  20. } else {
  21. [self setValue:[otherOptions objectForKey:key] forKey:key];
  22. }
  23. }
  24. }
  25. }
  26. -(void)mergeIfEmptyWith:(NSDictionary *)otherOptions {
  27. for (id key in otherOptions) {
  28. if ([self hasProperty:key]) {
  29. if ([[self valueForKey:key] isKindOfClass:[RNNOptions class]]) {
  30. RNNOptions* options = [self valueForKey:key];
  31. [options mergeIfEmptyWith:[otherOptions objectForKey:key]];
  32. } else if (![self valueForKey:key]) {
  33. [self setValue:[otherOptions objectForKey:key] forKey:key];
  34. }
  35. }
  36. }
  37. }
  38. - (BOOL)hasProperty:(NSString*)propName {
  39. return [self respondsToSelector:NSSelectorFromString(propName)];
  40. }
  41. - (void)initializeOptionsPropertiesWithDict:(NSDictionary*)dict {
  42. unsigned int count;
  43. objc_property_t* props = class_copyPropertyList([self class], &count);
  44. for (int i = 0; i < count; i++) {
  45. objc_property_t property = props[i];
  46. NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
  47. const char * type = property_getAttributes(property);
  48. NSString * typeString = [NSString stringWithUTF8String:type];
  49. NSArray * attributes = [typeString componentsSeparatedByString:@","];
  50. NSString * typeAttribute = [attributes objectAtIndex:0];
  51. if ([typeAttribute hasPrefix:@"T@"] && [typeAttribute length] > 3) {
  52. NSString * typeClassName = [typeAttribute substringWithRange:NSMakeRange(3, [typeAttribute length]-4)];
  53. Class typeClass = NSClassFromString(typeClassName);
  54. if ([typeClass isSubclassOfClass:[RNNOptions class]]) {
  55. RNNOptions* value = [[typeClass alloc] initWithDict:dict[propertyName]];
  56. [self setValue:value forKey:propertyName];
  57. }
  58. }
  59. }
  60. free(props);
  61. }
  62. @end