NSDictionary+ObjcRuntime.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // NSDictionary+ObjcRuntime.m
  3. // FLEX
  4. //
  5. // Derived from MirrorKit.
  6. // Created by Tanner on 7/5/15.
  7. // Copyright (c) 2020 FLEX Team. All rights reserved.
  8. //
  9. #import "NSDictionary+ObjcRuntime.h"
  10. #import "FLEXRuntimeUtility.h"
  11. @implementation NSDictionary (ObjcRuntime)
  12. /// See this link on how to construct a proper attributes string:
  13. /// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
  14. - (NSString *)propertyAttributesString {
  15. if (!self[kFLEXPropertyAttributeKeyTypeEncoding]) return nil;
  16. NSMutableString *attributes = [NSMutableString new];
  17. [attributes appendFormat:@"T%@,", self[kFLEXPropertyAttributeKeyTypeEncoding]];
  18. for (NSString *attribute in self.allKeys) {
  19. FLEXPropertyAttribute c = (FLEXPropertyAttribute)[attribute characterAtIndex:0];
  20. switch (c) {
  21. case FLEXPropertyAttributeTypeEncoding:
  22. break;
  23. case FLEXPropertyAttributeBackingIvarName:
  24. [attributes appendFormat:@"%@%@,",
  25. kFLEXPropertyAttributeKeyBackingIvarName,
  26. self[kFLEXPropertyAttributeKeyBackingIvarName]
  27. ];
  28. break;
  29. case FLEXPropertyAttributeCopy:
  30. if ([self[kFLEXPropertyAttributeKeyCopy] boolValue])
  31. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyCopy];
  32. break;
  33. case FLEXPropertyAttributeCustomGetter:
  34. [attributes appendFormat:@"%@%@,",
  35. kFLEXPropertyAttributeKeyCustomGetter,
  36. self[kFLEXPropertyAttributeKeyCustomGetter]
  37. ];
  38. break;
  39. case FLEXPropertyAttributeCustomSetter:
  40. [attributes appendFormat:@"%@%@,",
  41. kFLEXPropertyAttributeKeyCustomSetter,
  42. self[kFLEXPropertyAttributeKeyCustomSetter]
  43. ];
  44. break;
  45. case FLEXPropertyAttributeDynamic:
  46. if ([self[kFLEXPropertyAttributeKeyDynamic] boolValue])
  47. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyDynamic];
  48. break;
  49. case FLEXPropertyAttributeGarbageCollectible:
  50. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyGarbageCollectable];
  51. break;
  52. case FLEXPropertyAttributeNonAtomic:
  53. if ([self[kFLEXPropertyAttributeKeyNonAtomic] boolValue])
  54. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyNonAtomic];
  55. break;
  56. case FLEXPropertyAttributeOldTypeEncoding:
  57. [attributes appendFormat:@"%@%@,",
  58. kFLEXPropertyAttributeKeyOldStyleTypeEncoding,
  59. self[kFLEXPropertyAttributeKeyOldStyleTypeEncoding]
  60. ];
  61. break;
  62. case FLEXPropertyAttributeReadOnly:
  63. if ([self[kFLEXPropertyAttributeKeyReadOnly] boolValue])
  64. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyReadOnly];
  65. break;
  66. case FLEXPropertyAttributeRetain:
  67. if ([self[kFLEXPropertyAttributeKeyRetain] boolValue])
  68. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyRetain];
  69. break;
  70. case FLEXPropertyAttributeWeak:
  71. if ([self[kFLEXPropertyAttributeKeyWeak] boolValue])
  72. [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyWeak];
  73. break;
  74. default:
  75. return nil;
  76. break;
  77. }
  78. }
  79. [attributes deleteCharactersInRange:NSMakeRange(attributes.length-1, 1)];
  80. return attributes.copy;
  81. }
  82. + (instancetype)attributesDictionaryForProperty:(objc_property_t)property {
  83. NSMutableDictionary *attrs = [NSMutableDictionary new];
  84. for (NSString *key in FLEXRuntimeUtility.allPropertyAttributeKeys) {
  85. char *value = property_copyAttributeValue(property, key.UTF8String);
  86. if (value) {
  87. attrs[key] = [[NSString alloc]
  88. initWithBytesNoCopy:value
  89. length:strlen(value)
  90. encoding:NSUTF8StringEncoding
  91. freeWhenDone:YES
  92. ];
  93. }
  94. }
  95. return attrs.copy;
  96. }
  97. @end