react-native-navigation的迁移库

RNNOptions.m 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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)applyOn:(UIViewController *)viewController {
  15. }
  16. - (void)applyOnNavigationController:(UINavigationController *)navigationController {
  17. }
  18. - (void)applyOnTabBarController:(UITabBarController *)tabBarController {
  19. }
  20. - (void)mergeWith:(NSDictionary *)otherOptions {
  21. for (id key in otherOptions) {
  22. if ([self hasProperty:key]) {
  23. if ([[self valueForKey:key] isKindOfClass:[RNNOptions class]]) {
  24. RNNOptions* options = [self valueForKey:key];
  25. [options mergeWith:[otherOptions objectForKey:key]];
  26. } else {
  27. [self setValue:[otherOptions objectForKey:key] forKey:key];
  28. }
  29. }
  30. }
  31. }
  32. - (void)mergeOptions:(RNNOptions *)otherOptions overrideOptions:(BOOL)override {
  33. for (id prop in [self objectProperties:otherOptions]) {
  34. id value = [otherOptions valueForKey:prop];
  35. if ([value isKindOfClass:[RNNOptions class]]) {
  36. [[self valueForKey:prop] mergeOptions:value overrideOptions:override];
  37. } else if (value && (override || ![self valueForKey:prop])) {
  38. [self setValue:value forKey:prop];
  39. }
  40. }
  41. }
  42. - (void)mergeOptions:(RNNOptions *)otherOptions {
  43. [self mergeOptions:otherOptions overrideOptions:YES];
  44. }
  45. - (BOOL)hasProperty:(NSString*)propName {
  46. return [self respondsToSelector:NSSelectorFromString(propName)];
  47. }
  48. - (void)initializeOptionsPropertiesWithDict:(NSDictionary*)dict {
  49. unsigned int count;
  50. objc_property_t* props = class_copyPropertyList([self class], &count);
  51. for (int i = 0; i < count; i++) {
  52. objc_property_t property = props[i];
  53. NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
  54. const char * type = property_getAttributes(property);
  55. NSString * typeString = [NSString stringWithUTF8String:type];
  56. NSArray * attributes = [typeString componentsSeparatedByString:@","];
  57. NSString * typeAttribute = [attributes objectAtIndex:0];
  58. if ([typeAttribute hasPrefix:@"T@"] && [typeAttribute length] > 3) {
  59. NSString * typeClassName = [typeAttribute substringWithRange:NSMakeRange(3, [typeAttribute length]-4)];
  60. Class typeClass = NSClassFromString(typeClassName);
  61. if ([typeClass isSubclassOfClass:[RNNOptions class]]) {
  62. RNNOptions* value = [[typeClass alloc] initWithDict:dict[propertyName]];
  63. [self setValue:value forKey:propertyName];
  64. }
  65. }
  66. }
  67. free(props);
  68. }
  69. - (NSArray *)objectProperties:(NSObject *)object {
  70. NSMutableArray* properties = [NSMutableArray new];
  71. unsigned int count;
  72. objc_property_t* props = class_copyPropertyList([object class], &count);
  73. for (int i = 0; i < count; i++) {
  74. objc_property_t property = props[i];
  75. NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
  76. [properties addObject:propertyName];
  77. }
  78. free(props);
  79. return properties;
  80. }
  81. @end