| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | ////  YYClassInfo.h//  YYModel <https://github.com/ibireme/YYModel>////  Created by ibireme on 15/5/9.//  Copyright (c) 2015 ibireme.////  This source code is licensed under the MIT-style license found in the//  LICENSE file in the root directory of this source tree.//#import <Foundation/Foundation.h>#import <objc/runtime.h>NS_ASSUME_NONNULL_BEGIN/** Type encoding's type. */typedef NS_OPTIONS(NSUInteger, YYEncodingType) {    YYEncodingTypeMask       = 0xFF, ///< mask of type value    YYEncodingTypeUnknown    = 0, ///< unknown    YYEncodingTypeVoid       = 1, ///< void    YYEncodingTypeBool       = 2, ///< bool    YYEncodingTypeInt8       = 3, ///< char / BOOL    YYEncodingTypeUInt8      = 4, ///< unsigned char    YYEncodingTypeInt16      = 5, ///< short    YYEncodingTypeUInt16     = 6, ///< unsigned short    YYEncodingTypeInt32      = 7, ///< int    YYEncodingTypeUInt32     = 8, ///< unsigned int    YYEncodingTypeInt64      = 9, ///< long long    YYEncodingTypeUInt64     = 10, ///< unsigned long long    YYEncodingTypeFloat      = 11, ///< float    YYEncodingTypeDouble     = 12, ///< double    YYEncodingTypeLongDouble = 13, ///< long double    YYEncodingTypeObject     = 14, ///< id    YYEncodingTypeClass      = 15, ///< Class    YYEncodingTypeSEL        = 16, ///< SEL    YYEncodingTypeBlock      = 17, ///< block    YYEncodingTypePointer    = 18, ///< void*    YYEncodingTypeStruct     = 19, ///< struct    YYEncodingTypeUnion      = 20, ///< union    YYEncodingTypeCString    = 21, ///< char*    YYEncodingTypeCArray     = 22, ///< char[10] (for example)        YYEncodingTypeQualifierMask   = 0xFF00,   ///< mask of qualifier    YYEncodingTypeQualifierConst  = 1 << 8,  ///< const    YYEncodingTypeQualifierIn     = 1 << 9,  ///< in    YYEncodingTypeQualifierInout  = 1 << 10, ///< inout    YYEncodingTypeQualifierOut    = 1 << 11, ///< out    YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy    YYEncodingTypeQualifierByref  = 1 << 13, ///< byref    YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway        YYEncodingTypePropertyMask         = 0xFF0000, ///< mask of property    YYEncodingTypePropertyReadonly     = 1 << 16, ///< readonly    YYEncodingTypePropertyCopy         = 1 << 17, ///< copy    YYEncodingTypePropertyRetain       = 1 << 18, ///< retain    YYEncodingTypePropertyNonatomic    = 1 << 19, ///< nonatomic    YYEncodingTypePropertyWeak         = 1 << 20, ///< weak    YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=    YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=    YYEncodingTypePropertyDynamic      = 1 << 23, ///< @dynamic};/** Get the type from a Type-Encoding string.  @discussion See also: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html  @param typeEncoding  A Type-Encoding string. @return The encoding type. */YYEncodingType YYEncodingGetType(const char *typeEncoding);/** Instance variable information. */@interface YYClassIvarInfo : NSObject@property (nonatomic, assign, readonly) Ivar ivar;              ///< ivar opaque struct@property (nonatomic, strong, readonly) NSString *name;         ///< Ivar's name@property (nonatomic, assign, readonly) ptrdiff_t offset;       ///< Ivar's offset@property (nonatomic, strong, readonly) NSString *typeEncoding; ///< Ivar's type encoding@property (nonatomic, assign, readonly) YYEncodingType type;    ///< Ivar's type/** Creates and returns an ivar info object.  @param ivar ivar opaque struct @return A new object, or nil if an error occurs. */- (instancetype)initWithIvar:(Ivar)ivar;@end/** Method information. */@interface YYClassMethodInfo : NSObject@property (nonatomic, assign, readonly) Method method;                  ///< method opaque struct@property (nonatomic, strong, readonly) NSString *name;                 ///< method name@property (nonatomic, assign, readonly) SEL sel;                        ///< method's selector@property (nonatomic, assign, readonly) IMP imp;                        ///< method's implementation@property (nonatomic, strong, readonly) NSString *typeEncoding;         ///< method's parameter and return types@property (nonatomic, strong, readonly) NSString *returnTypeEncoding;   ///< return value's type@property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *argumentTypeEncodings; ///< array of arguments' type/** Creates and returns a method info object.  @param method method opaque struct @return A new object, or nil if an error occurs. */- (instancetype)initWithMethod:(Method)method;@end/** Property information. */@interface YYClassPropertyInfo : NSObject@property (nonatomic, assign, readonly) objc_property_t property; ///< property's opaque struct@property (nonatomic, strong, readonly) NSString *name;           ///< property's name@property (nonatomic, assign, readonly) YYEncodingType type;      ///< property's type@property (nonatomic, strong, readonly) NSString *typeEncoding;   ///< property's encoding value@property (nonatomic, strong, readonly) NSString *ivarName;       ///< property's ivar name@property (nullable, nonatomic, assign, readonly) Class cls;      ///< may be nil@property (nullable, nonatomic, strong, readonly) NSArray<NSString *> *protocols; ///< may nil@property (nonatomic, assign, readonly) SEL getter;               ///< getter (nonnull)@property (nonatomic, assign, readonly) SEL setter;               ///< setter (nonnull)/** Creates and returns a property info object.  @param property property opaque struct @return A new object, or nil if an error occurs. */- (instancetype)initWithProperty:(objc_property_t)property;@end/** Class information for a class. */@interface YYClassInfo : NSObject@property (nonatomic, assign, readonly) Class cls; ///< class object@property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object@property (nullable, nonatomic, assign, readonly) Class metaCls;  ///< class's meta class object@property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class@property (nonatomic, strong, readonly) NSString *name; ///< class name@property (nullable, nonatomic, strong, readonly) YYClassInfo *superClassInfo; ///< super class's class info@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassIvarInfo *> *ivarInfos; ///< ivars@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassMethodInfo *> *methodInfos; ///< methods@property (nullable, nonatomic, strong, readonly) NSDictionary<NSString *, YYClassPropertyInfo *> *propertyInfos; ///< properties/** If the class is changed (for example: you add a method to this class with 'class_addMethod()'), you should call this method to refresh the class info cache.  After called this method, `needUpdate` will returns `YES`, and you should call  'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info. */- (void)setNeedUpdate;/** If this method returns `YES`, you should stop using this instance and call `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.  @return Whether this class info need update. */- (BOOL)needUpdate;/** Get the class info of a specified Class.  @discussion This method will cache the class info and super-class info at the first access to the Class. This method is thread-safe.  @param cls A class. @return A class info, or nil if an error occurs. */+ (nullable instancetype)classInfoWithClass:(Class)cls;/** Get the class info of a specified Class.  @discussion This method will cache the class info and super-class info at the first access to the Class. This method is thread-safe.  @param className A class name. @return A class info, or nil if an error occurs. */+ (nullable instancetype)classInfoWithClassName:(NSString *)className;@endNS_ASSUME_NONNULL_END
 |