DKClassInfo.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // DKClassInfo.h
  3. // DKModel
  4. //
  5. // Created by dongke on 17/5/9.
  6. // Copyright (c) 2017 dongke.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import <Foundation/Foundation.h>
  12. #import <objc/runtime.h>
  13. NS_ASSUME_NONNULL_BEGIN
  14. /**
  15. Type encoding's type.
  16. */
  17. typedef NS_OPTIONS(NSUInteger, DKEncodingType) {
  18. DKEncodingTypeMask = 0xFF, ///< mask of type value
  19. DKEncodingTypeUnknown = 0, ///< unknown
  20. DKEncodingTypeVoid = 1, ///< void
  21. DKEncodingTypeBool = 2, ///< bool
  22. DKEncodingTypeInt8 = 3, ///< char / BOOL
  23. DKEncodingTypeUInt8 = 4, ///< unsigned char
  24. DKEncodingTypeInt16 = 5, ///< short
  25. DKEncodingTypeUInt16 = 6, ///< unsigned short
  26. DKEncodingTypeInt32 = 7, ///< int
  27. DKEncodingTypeUInt32 = 8, ///< unsigned int
  28. DKEncodingTypeInt64 = 9, ///< long long
  29. DKEncodingTypeUInt64 = 10, ///< unsigned long long
  30. DKEncodingTypeFloat = 11, ///< float
  31. DKEncodingTypeDouble = 12, ///< double
  32. DKEncodingTypeLongDouble = 13, ///< long double
  33. DKEncodingTypeObject = 14, ///< id
  34. DKEncodingTypeClass = 15, ///< Class
  35. DKEncodingTypeSEL = 16, ///< SEL
  36. DKEncodingTypeBlock = 17, ///< block
  37. DKEncodingTypePointer = 18, ///< void*
  38. DKEncodingTypeStruct = 19, ///< struct
  39. DKEncodingTypeUnion = 20, ///< union
  40. DKEncodingTypeCString = 21, ///< char*
  41. DKEncodingTypeCArray = 22, ///< char[10] (for example)
  42. DKEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier
  43. DKEncodingTypeQualifierConst = 1 << 8, ///< const
  44. DKEncodingTypeQualifierIn = 1 << 9, ///< in
  45. DKEncodingTypeQualifierInout = 1 << 10, ///< inout
  46. DKEncodingTypeQualifierOut = 1 << 11, ///< out
  47. DKEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
  48. DKEncodingTypeQualifierByref = 1 << 13, ///< byref
  49. DKEncodingTypeQualifierOneway = 1 << 14, ///< oneway
  50. DKEncodingTypePropertyMask = 0xFF0000, ///< mask of property
  51. DKEncodingTypePropertyReadonly = 1 << 16, ///< readonly
  52. DKEncodingTypePropertyCopy = 1 << 17, ///< copy
  53. DKEncodingTypePropertyRetain = 1 << 18, ///< retain
  54. DKEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic
  55. DKEncodingTypePropertyWeak = 1 << 20, ///< weak
  56. DKEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
  57. DKEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
  58. DKEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic
  59. };
  60. /**
  61. Get the type from a Type-Encoding string.
  62. @discussion See also:
  63. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
  64. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
  65. @param typeEncoding A Type-Encoding string.
  66. @return The encoding type.
  67. */
  68. DKEncodingType DKEncodingGetType(const char *typeEncoding);
  69. /**
  70. Instance variable information.
  71. */
  72. @interface DKClassIvarInfo : NSObject
  73. @property (nonatomic, assign, readonly) Ivar ivar; ///< ivar opaque struct
  74. @property (nonatomic, strong, readonly) NSString *name; ///< Ivar's name
  75. @property (nonatomic, assign, readonly) ptrdiff_t offset; ///< Ivar's offset
  76. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< Ivar's type encoding
  77. @property (nonatomic, assign, readonly) DKEncodingType type; ///< Ivar's type
  78. /**
  79. Creates and returns an ivar info object.
  80. @param ivar ivar opaque struct
  81. @return A new object, or nil if an error occurs.
  82. */
  83. - (instancetype)initWithIvar:(Ivar)ivar;
  84. @end
  85. /**
  86. Method information.
  87. */
  88. @interface DKClassMethodInfo : NSObject
  89. @property (nonatomic, assign, readonly) Method method; ///< method opaque struct
  90. @property (nonatomic, strong, readonly) NSString *name; ///< method name
  91. @property (nonatomic, assign, readonly) SEL sel; ///< method's selector
  92. @property (nonatomic, assign, readonly) IMP imp; ///< method's implementation
  93. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< method's parameter and return types
  94. @property (nonatomic, strong, readonly) NSString *returnTypeEncoding; ///< return value's type
  95. @property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *argumentTypeEncodings; ///< array of arguments' type
  96. /**
  97. Creates and returns a method info object.
  98. @param method method opaque struct
  99. @return A new object, or nil if an error occurs.
  100. */
  101. - (instancetype)initWithMethod:(Method)method;
  102. @end
  103. /**
  104. Property information.
  105. */
  106. @interface DKClassPropertyInfo : NSObject
  107. @property (nonatomic, assign, readonly) objc_property_t property; ///< property's opaque struct
  108. @property (nonatomic, strong, readonly) NSString *name; ///< property's name
  109. @property (nonatomic, assign, readonly) DKEncodingType type; ///< property's type
  110. @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< property's encoding value
  111. @property (nonatomic, strong, readonly) NSString *ivarName; ///< property's ivar name
  112. @property (nullable, nonatomic, assign, readonly) Class cls; ///< may be nil
  113. @property (nonatomic, assign, readonly) SEL getter; ///< getter (nonnull)
  114. @property (nonatomic, assign, readonly) SEL setter; ///< setter (nonnull)
  115. /**
  116. Creates and returns a property info object.
  117. @param property property opaque struct
  118. @return A new object, or nil if an error occurs.
  119. */
  120. - (instancetype)initWithProperty:(objc_property_t)property;
  121. @end
  122. /**
  123. Class information for a class.
  124. */
  125. @interface DKClassInfo : NSObject
  126. @property (nonatomic, assign, readonly) Class cls; ///< class object
  127. @property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object
  128. @property (nullable, nonatomic, assign, readonly) Class metaCls; ///< class's meta class object
  129. @property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class
  130. @property (nonatomic, strong, readonly) NSString *name; ///< class name
  131. @property (nullable, nonatomic, strong, readonly) DKClassInfo *superClassInfo; ///< super class's class info
  132. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, DKClassIvarInfo *> *ivarInfos; ///< ivars
  133. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, DKClassMethodInfo *> *methodInfos; ///< methods
  134. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, DKClassPropertyInfo *> *propertyInfos; ///< properties
  135. /**
  136. If the class is changed (for example: you add a method to this class with
  137. 'class_addMethod()'), you should call this method to refresh the class info cache.
  138. After called this method, `needUpdate` will returns `YES`, and you should call
  139. 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info.
  140. */
  141. - (void)setNeedUpdate;
  142. /**
  143. If this method returns `YES`, you should stop using this instance and call
  144. `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.
  145. @return Whether this class info need update.
  146. */
  147. - (BOOL)needUpdate;
  148. /**
  149. Get the class info of a specified Class.
  150. @discussion This method will cache the class info and super-class info
  151. at the first access to the Class. This method is thread-safe.
  152. @param cls A class.
  153. @return A class info, or nil if an error occurs.
  154. */
  155. + (nullable instancetype)classInfoWithClass:(Class)cls;
  156. /**
  157. Get the class info of a specified Class.
  158. @discussion This method will cache the class info and super-class info
  159. at the first access to the Class. This method is thread-safe.
  160. @param className A class name.
  161. @return A class info, or nil if an error occurs.
  162. */
  163. + (nullable instancetype)classInfoWithClassName:(NSString *)className;
  164. @end
  165. NS_ASSUME_NONNULL_END