BUYYClassInfo.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //
  2. // BUYYClassInfo.h
  3. // BUYYModel
  4. //
  5. // This source code is licensed under the MIT-style license found in the
  6. // LICENSE file in the root directory of this source tree.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import <objc/runtime.h>
  10. NS_ASSUME_NONNULL_BEGIN
  11. /**
  12. Type encoding's type.
  13. */
  14. typedef NS_OPTIONS(NSUInteger, BUYYEncodingType) {
  15. BUYYEncodingTypeMask = 0xFF, ///< mask of type value
  16. BUYYEncodingTypeUnknown = 0, ///< unknown
  17. BUYYEncodingTypeVoid = 1, ///< void
  18. BUYYEncodingTypeBool = 2, ///< bool
  19. BUYYEncodingTypeInt8 = 3, ///< char / BOOL
  20. BUYYEncodingTypeUInt8 = 4, ///< unsigned char
  21. BUYYEncodingTypeInt16 = 5, ///< short
  22. BUYYEncodingTypeUInt16 = 6, ///< unsigned short
  23. BUYYEncodingTypeInt32 = 7, ///< int
  24. BUYYEncodingTypeUInt32 = 8, ///< unsigned int
  25. BUYYEncodingTypeInt64 = 9, ///< long long
  26. BUYYEncodingTypeUInt64 = 10, ///< unsigned long long
  27. BUYYEncodingTypeFloat = 11, ///< float
  28. BUYYEncodingTypeDouble = 12, ///< double
  29. BUYYEncodingTypeLongDouble = 13, ///< long double
  30. BUYYEncodingTypeObject = 14, ///< id
  31. BUYYEncodingTypeClass = 15, ///< Class
  32. BUYYEncodingTypeSEL = 16, ///< SEL
  33. BUYYEncodingTypeBlock = 17, ///< block
  34. BUYYEncodingTypePointer = 18, ///< void*
  35. BUYYEncodingTypeStruct = 19, ///< struct
  36. BUYYEncodingTypeUnion = 20, ///< union
  37. BUYYEncodingTypeCString = 21, ///< char*
  38. BUYYEncodingTypeCArray = 22, ///< char[10] (for example)
  39. BUYYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier
  40. BUYYEncodingTypeQualifierConst = 1 << 8, ///< const
  41. BUYYEncodingTypeQualifierIn = 1 << 9, ///< in
  42. BUYYEncodingTypeQualifierInout = 1 << 10, ///< inout
  43. BUYYEncodingTypeQualifierOut = 1 << 11, ///< out
  44. BUYYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
  45. BUYYEncodingTypeQualifierByref = 1 << 13, ///< byref
  46. BUYYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
  47. BUYYEncodingTypePropertyMask = 0xFF0000, ///< mask of property
  48. BUYYEncodingTypePropertyReadonly = 1 << 16, ///< readonly
  49. BUYYEncodingTypePropertyCopy = 1 << 17, ///< copy
  50. BUYYEncodingTypePropertyRetain = 1 << 18, ///< retain
  51. BUYYEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic
  52. BUYYEncodingTypePropertyWeak = 1 << 20, ///< weak
  53. BUYYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
  54. BUYYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
  55. BUYYEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic
  56. };
  57. /**
  58. Get the type from a Type-Encoding string.
  59. @discussion See also:
  60. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
  61. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
  62. @param typeEncoding A Type-Encoding string.
  63. @return The encoding type.
  64. */
  65. BUYYEncodingType BUYYEncodingGetType(const char *typeEncoding);
  66. /**
  67. Instance variable information.
  68. */
  69. @interface BUYYClassIvarInfo : NSObject
  70. @property (nonatomic, assign, readonly) Ivar ivar; ///< ivar opaque struct
  71. @property (nonatomic, strong, readonly) NSString *name; ///< Ivar's name
  72. @property (nonatomic, assign, readonly) ptrdiff_t offset; ///< Ivar's offset
  73. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< Ivar's type encoding
  74. @property (nonatomic, assign, readonly) BUYYEncodingType type; ///< Ivar's type
  75. /**
  76. Creates and returns an ivar info object.
  77. @param ivar ivar opaque struct
  78. @return A new object, or nil if an error occurs.
  79. */
  80. - (instancetype)initWithIvar:(Ivar)ivar;
  81. @end
  82. /**
  83. Method information.
  84. */
  85. @interface BUYYClassMethodInfo : NSObject
  86. @property (nonatomic, assign, readonly) Method method; ///< method opaque struct
  87. @property (nonatomic, strong, readonly) NSString *name; ///< method name
  88. @property (nonatomic, assign, readonly) SEL sel; ///< method's selector
  89. @property (nonatomic, assign, readonly) IMP imp; ///< method's implementation
  90. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< method's parameter and return types
  91. @property (nonatomic, strong, readonly) NSString *returnTypeEncoding; ///< return value's type
  92. @property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *argumentTypeEncodings; ///< array of arguments' type
  93. /**
  94. Creates and returns a method info object.
  95. @param method method opaque struct
  96. @return A new object, or nil if an error occurs.
  97. */
  98. - (instancetype)initWithMethod:(Method)method;
  99. @end
  100. /**
  101. Property information.
  102. */
  103. @interface BUYYClassPropertyInfo : NSObject
  104. @property (nonatomic, assign, readonly) objc_property_t property; ///< property's opaque struct
  105. @property (nonatomic, strong, readonly) NSString *name; ///< property's name
  106. @property (nonatomic, assign, readonly) BUYYEncodingType type; ///< property's type
  107. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< property's encoding value
  108. @property (nonatomic, strong, readonly) NSString *ivarName; ///< property's ivar name
  109. @property (nullable, nonatomic, assign, readonly) Class cls; ///< may be nil
  110. @property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *protocols; ///< may nil
  111. @property (nonatomic, assign, readonly) SEL getter; ///< getter (nonnull)
  112. @property (nonatomic, assign, readonly) SEL setter; ///< setter (nonnull)
  113. /**
  114. Creates and returns a property info object.
  115. @param property property opaque struct
  116. @return A new object, or nil if an error occurs.
  117. */
  118. - (instancetype)initWithProperty:(objc_property_t)property;
  119. @end
  120. /**
  121. Class information for a class.
  122. */
  123. @interface BUYYClassInfo : NSObject
  124. @property (nonatomic, assign, readonly) Class cls; ///< class object
  125. @property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object
  126. @property (nullable, nonatomic, assign, readonly) Class metaCls; ///< class's meta class object
  127. @property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class
  128. @property (nonatomic, strong, readonly) NSString *name; ///< class name
  129. @property (nullable, nonatomic, strong, readonly) BUYYClassInfo *superClassInfo; ///< super class's class info
  130. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, BUYYClassIvarInfo *> *ivarInfos; ///< ivars
  131. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, BUYYClassMethodInfo *> *methodInfos; ///< methods
  132. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, BUYYClassPropertyInfo *> *propertyInfos; ///< properties
  133. /**
  134. If the class is changed (for example: you add a method to this class with
  135. 'class_addMethod()'), you should call this method to refresh the class info cache.
  136. After called this method, `needUpdate` will returns `YES`, and you should call
  137. 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info.
  138. */
  139. - (void)setNeedUpdate;
  140. /**
  141. If this method returns `YES`, you should stop using this instance and call
  142. `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.
  143. @return Whether this class info need update.
  144. */
  145. - (BOOL)needUpdate;
  146. /**
  147. Get the class info of a specified Class.
  148. @discussion This method will cache the class info and super-class info
  149. at the first access to the Class. This method is thread-safe.
  150. @param cls A class.
  151. @return A class info, or nil if an error occurs.
  152. */
  153. + (nullable instancetype)classInfoWithClass:(Class)cls;
  154. /**
  155. Get the class info of a specified Class.
  156. @discussion This method will cache the class info and super-class info
  157. at the first access to the Class. This method is thread-safe.
  158. @param className A class name.
  159. @return A class info, or nil if an error occurs.
  160. */
  161. + (nullable instancetype)classInfoWithClassName:(NSString *)className;
  162. @end
  163. NS_ASSUME_NONNULL_END