YYClassInfo.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //
  2. // YYClassInfo.h
  3. // YYKit <https://github.com/ibireme/YYKit>
  4. //
  5. // Created by ibireme on 15/5/9.
  6. // Copyright (c) 2015 ibireme.
  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, YYEncodingType) {
  18. YYEncodingTypeMask = 0xFF, ///< mask of type value
  19. YYEncodingTypeUnknown = 0, ///< unknown
  20. YYEncodingTypeVoid = 1, ///< void
  21. YYEncodingTypeBool = 2, ///< bool
  22. YYEncodingTypeInt8 = 3, ///< char / BOOL
  23. YYEncodingTypeUInt8 = 4, ///< unsigned char
  24. YYEncodingTypeInt16 = 5, ///< short
  25. YYEncodingTypeUInt16 = 6, ///< unsigned short
  26. YYEncodingTypeInt32 = 7, ///< int
  27. YYEncodingTypeUInt32 = 8, ///< unsigned int
  28. YYEncodingTypeInt64 = 9, ///< long long
  29. YYEncodingTypeUInt64 = 10, ///< unsigned long long
  30. YYEncodingTypeFloat = 11, ///< float
  31. YYEncodingTypeDouble = 12, ///< double
  32. YYEncodingTypeLongDouble = 13, ///< long double
  33. YYEncodingTypeObject = 14, ///< id
  34. YYEncodingTypeClass = 15, ///< Class
  35. YYEncodingTypeSEL = 16, ///< SEL
  36. YYEncodingTypeBlock = 17, ///< block
  37. YYEncodingTypePointer = 18, ///< void*
  38. YYEncodingTypeStruct = 19, ///< struct
  39. YYEncodingTypeUnion = 20, ///< union
  40. YYEncodingTypeCString = 21, ///< char*
  41. YYEncodingTypeCArray = 22, ///< char[10] (for example)
  42. YYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier
  43. YYEncodingTypeQualifierConst = 1 << 8, ///< const
  44. YYEncodingTypeQualifierIn = 1 << 9, ///< in
  45. YYEncodingTypeQualifierInout = 1 << 10, ///< inout
  46. YYEncodingTypeQualifierOut = 1 << 11, ///< out
  47. YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
  48. YYEncodingTypeQualifierByref = 1 << 13, ///< byref
  49. YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
  50. YYEncodingTypePropertyMask = 0xFF0000, ///< mask of property
  51. YYEncodingTypePropertyReadonly = 1 << 16, ///< readonly
  52. YYEncodingTypePropertyCopy = 1 << 17, ///< copy
  53. YYEncodingTypePropertyRetain = 1 << 18, ///< retain
  54. YYEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic
  55. YYEncodingTypePropertyWeak = 1 << 20, ///< weak
  56. YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
  57. YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
  58. YYEncodingTypePropertyDynamic = 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. YYEncodingType YYEncodingGetType(const char *typeEncoding);
  69. /**
  70. Instance variable information.
  71. */
  72. @interface YYClassIvarInfo : 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) YYEncodingType 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 YYClassMethodInfo : 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 YYClassPropertyInfo : 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) YYEncodingType 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 (nullable, nonatomic, strong, readonly) NSArray<NSString *> *protocols; ///< may nil
  114. @property (nonatomic, assign, readonly) SEL getter; ///< getter (nonnull)
  115. @property (nonatomic, assign, readonly) SEL setter; ///< setter (nonnull)
  116. /**
  117. Creates and returns a property info object.
  118. @param property property opaque struct
  119. @return A new object, or nil if an error occurs.
  120. */
  121. - (instancetype)initWithProperty:(objc_property_t)property;
  122. @end
  123. /**
  124. Class information for a class.
  125. */
  126. @interface YYClassInfo : NSObject
  127. @property (nonatomic, assign, readonly) Class cls; ///< class object
  128. @property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object
  129. @property (nullable, nonatomic, assign, readonly) Class metaCls; ///< class's meta class object
  130. @property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class
  131. @property (nonatomic, strong, readonly) NSString *name; ///< class name
  132. @property (nullable, nonatomic, strong, readonly) YYClassInfo *superClassInfo; ///< super class's class info
  133. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassIvarInfo *> *ivarInfos; ///< ivars
  134. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassMethodInfo *> *methodInfos; ///< methods
  135. @property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassPropertyInfo *> *propertyInfos; ///< properties
  136. /**
  137. If the class is changed (for example: you add a method to this class with
  138. 'class_addMethod()'), you should call this method to refresh the class info cache.
  139. After called this method, `needUpdate` will returns `YES`, and you should call
  140. 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info.
  141. */
  142. - (void)setNeedUpdate;
  143. /**
  144. If this method returns `YES`, you should stop using this instance and call
  145. `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.
  146. @return Whether this class info need update.
  147. */
  148. - (BOOL)needUpdate;
  149. /**
  150. Get the class info of a specified Class.
  151. @discussion This method will cache the class info and super-class info
  152. at the first access to the Class. This method is thread-safe.
  153. @param cls A class.
  154. @return A class info, or nil if an error occurs.
  155. */
  156. + (nullable instancetype)classInfoWithClass:(Class)cls;
  157. /**
  158. Get the class info of a specified Class.
  159. @discussion This method will cache the class info and super-class info
  160. at the first access to the Class. This method is thread-safe.
  161. @param className A class name.
  162. @return A class info, or nil if an error occurs.
  163. */
  164. + (nullable instancetype)classInfoWithClassName:(NSString *)className;
  165. @end
  166. NS_ASSUME_NONNULL_END