NSObject(QMUI)

@interface NSObject (QMUI)

/**
 判断当前类是否有重写某个父类的指定方法
 
 @param selector 要判断的方法
 @param superclass 要比较的父类,必须是当前类的某个 superclass
 @return YES 表示子类有重写了父类方法,NO 表示没有重写(异常情况也返回 NO,例如当前类与指定的类并非父子关系、父类本身也无法响应指定的方法)
 */
- (BOOL)qmui_hasOverrideMethod:(SEL)selector ofSuperclass:(Class)superclass;

/**
 判断指定的类是否有重写某个父类的指定方法
 
 @param selector 要判断的方法
 @param superclass 要比较的父类,必须是当前类的某个 superclass
 @return YES 表示子类有重写了父类方法,NO 表示没有重写(异常情况也返回 NO,例如当前类与指定的类并非父子关系、父类本身也无法响应指定的方法)
 */
+ (BOOL)qmui_hasOverrideMethod:(SEL)selector forClass:(Class)aClass ofSuperclass:(Class)superclass;

/**
 对 super 发送消息
 
 @param aSelector 要发送的消息
 @return 消息执行后的结果
 @link http://stackoverflow.com/questions/14635024/using-objc-msgsendsuper-to-invoke-a-class-method @/link
 */
- (nullable id)qmui_performSelectorToSuperclass:(SEL)aSelector;

/**
 对 super 发送消息
 
 @param aSelector 要发送的消息
 @param object 作为参数传过去
 @return 消息执行后的结果
 @link http://stackoverflow.com/questions/14635024/using-objc-msgsendsuper-to-invoke-a-class-method @/link
 */
- (nullable id)qmui_performSelectorToSuperclass:(SEL)aSelector withObject:(nullable id)object;

/**
 *  调用一个无参数、返回值类型为非对象的 selector。如果返回值类型为对象,请直接使用系统的 performSelector: 方法。
 *  @param selector 要被调用的方法名
 *  @param returnValue selector 的返回值的指针地址,请先定义一个变量再将其指针地址传进来,例如 &result
 *
 *  @code
 *  CGFloat alpha;
 *  [view qmui_performSelector:@selector(alpha) withPrimitiveReturnValue:&alpha];
 *  @endcode
 */
- (void)qmui_performSelector:(SEL)selector withPrimitiveReturnValue:(nullable void *)returnValue;

/**
 *  调用一个带参数的 selector,参数类型支持对象和非对象,也没有数量限制。返回值为对象或者 void。
 *  @param selector 要被调用的方法名
 *  @param firstArgument 参数列表,请传参数的指针地址,支持多个参数
 *  @return 方法的返回值,如果该方法返回类型为 void,则会返回 nil,如果返回类型为对象,则返回该对象。
 *
 *  @code
 *  id target = xxx;
 *  SEL action = xxx;
 *  UIControlEvents events = xxx;
 *  [control qmui_performSelector:@selector(addTarget:action:forControlEvents:) withArguments:&target, &action, &events, nil];
 *  @endcode
 */
- (nullable id)qmui_performSelector:(SEL)selector withArguments:(nullable void *)firstArgument, ...;

/**
 *  调用一个返回值类型为非对象且带参数的 selector,参数类型支持对象和非对象,也没有数量限制。
 *
 *  @param selector 要被调用的方法名
 *  @param returnValue selector 的返回值的指针地址
 *  @param firstArgument 参数列表,请传参数的指针地址,支持多个参数
 *
 *  @code
 *  CGPoint point = xxx;
 *  UIEvent *event = xxx;
 *  BOOL isInside;
 *  [view qmui_performSelector:@selector(pointInside:withEvent:) withPrimitiveReturnValue:&isInside arguments:&point, &event, nil];
 *  @endcode
 */
- (void)qmui_performSelector:(SEL)selector withPrimitiveReturnValue:(nullable void *)returnValue arguments:(nullable void *)firstArgument, ...;


/**
 使用 block 遍历指定 class 的所有成员变量(也即 _xxx 那种),不包含 property 对应的 _property 成员变量,也不包含 superclasses 里定义的变量
 
 @param block 用于遍历的 block
 */
- (void)qmui_enumrateIvarsUsingBlock:(void (^)(Ivar ivar, NSString *ivarDescription))block;

/**
 使用 block 遍历指定 class 的所有成员变量(也即 _xxx 那种),不包含 property 对应的 _property 成员变量
 
 @param aClass 指定的 class
 @param includingInherited 是否要包含由继承链带过来的 ivars
 @param block  用于遍历的 block
 */
+ (void)qmui_enumrateIvarsOfClass:(Class)aClass includingInherited:(BOOL)includingInherited usingBlock:(void (^)(Ivar ivar, NSString *ivarDescription))block;

/**
 使用 block 遍历指定 class 的所有属性,不包含 superclasses 里定义的 property
 
 @param block 用于遍历的 block,如果要获取 property 的信息,推荐用 QMUIPropertyDescriptor。
 */
- (void)qmui_enumratePropertiesUsingBlock:(void (^)(objc_property_t property, NSString *propertyName))block;

/**
 使用 block 遍历指定 class 的所有属性
 
 @param aClass 指定的 class
 @param includingInherited 是否要包含由继承链带过来的 property
 @param block 用于遍历的 block,如果要获取 property 的信息,推荐用 QMUIPropertyDescriptor。
 @see https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW1
 */
+ (void)qmui_enumratePropertiesOfClass:(Class)aClass includingInherited:(BOOL)includingInherited usingBlock:(void (^)(objc_property_t property, NSString *propertyName))block;

/**
 使用 block 遍历当前实例的所有方法,不包含 superclasses 里定义的 method
 */
- (void)qmui_enumrateInstanceMethodsUsingBlock:(void (^)(Method method, SEL selector))block;

/**
 使用 block 遍历指定的某个类的实例方法
 @param aClass   指定的 class
 @param includingInherited 是否要包含由继承链带过来的 method
 @param block    用于遍历的 block
 */
+ (void)qmui_enumrateInstanceMethodsOfClass:(Class)aClass includingInherited:(BOOL)includingInherited usingBlock:(void (^)(Method method, SEL selector))block;

/**
 遍历某个 protocol 里的所有方法
 
 @param protocol 要遍历的 protocol,例如 \@protocol(xxx)
 @param block 遍历过程中调用的 block
 */
+ (void)qmui_enumerateProtocolMethods:(Protocol *)protocol usingBlock:(void (^)(SEL selector))block;

@end

Undocumented

  • 判断当前类是否有重写某个父类的指定方法

    Declaration

    Objective-C

    - (BOOL)qmui_hasOverrideMethod:(nonnull SEL)selector
                      ofSuperclass:(nonnull Class)superclass;

    Swift

    func qmui_hasOverrideMethod(_ selector: Selector, ofSuperclass superclass: AnyClass) -> Bool

    Parameters

    selector

    要判断的方法

    superclass

    要比较的父类,必须是当前类的某个 superclass

    Return Value

    YES 表示子类有重写了父类方法,NO 表示没有重写(异常情况也返回 NO,例如当前类与指定的类并非父子关系、父类本身也无法响应指定的方法)

  • 判断指定的类是否有重写某个父类的指定方法

    Declaration

    Objective-C

    + (BOOL)qmui_hasOverrideMethod:(nonnull SEL)selector
                          forClass:(nonnull Class)aClass
                      ofSuperclass:(nonnull Class)superclass;

    Swift

    class func qmui_hasOverrideMethod(_ selector: Selector, for aClass: AnyClass, ofSuperclass superclass: AnyClass) -> Bool

    Parameters

    selector

    要判断的方法

    superclass

    要比较的父类,必须是当前类的某个 superclass

    Return Value

    YES 表示子类有重写了父类方法,NO 表示没有重写(异常情况也返回 NO,例如当前类与指定的类并非父子关系、父类本身也无法响应指定的方法)

  • 对 super 发送消息

    Declaration

    Objective-C

    - (nullable id)qmui_performSelectorToSuperclass:(nonnull SEL)aSelector;

    Swift

    func qmui_performSelector(toSuperclass aSelector: Selector) -> Any?

    Parameters

    aSelector

    要发送的消息

  • 对 super 发送消息

    Declaration

    Objective-C

    - (nullable id)qmui_performSelectorToSuperclass:(nonnull SEL)aSelector
                                         withObject:(nullable id)object;

    Swift

    func qmui_performSelector(toSuperclass aSelector: Selector, with object: Any?) -> Any?

    Parameters

    aSelector

    要发送的消息

    object

    作为参数传过去

  • 调用一个无参数、返回值类型为非对象的 selector。如果返回值类型为对象,请直接使用系统的 performSelector: 方法。

      CGFloat alpha;
      [view qmui_performSelector:@selector(alpha) withPrimitiveReturnValue:&alpha];
    

    Declaration

    Objective-C

    - (void)qmui_performSelector:(nonnull SEL)selector
        withPrimitiveReturnValue:(nullable void *)returnValue;

    Swift

    func qmui_perform(_ selector: Selector, withPrimitiveReturnValue returnValue: UnsafeMutableRawPointer?)

    Parameters

    selector

    要被调用的方法名

    returnValue

    selector 的返回值的指针地址,请先定义一个变量再将其指针地址传进来,例如 &result

  • 调用一个带参数的 selector,参数类型支持对象和非对象,也没有数量限制。返回值为对象或者 void。

      id target = xxx;
      SEL action = xxx;
      UIControlEvents events = xxx;
      [control qmui_performSelector:@selector(addTarget:action:forControlEvents:) withArguments:&target, &action, &events, nil];
    

    Declaration

    Objective-C

    - (nullable id)qmui_performSelector:(nonnull SEL)selector
                          withArguments:(nullable void *)firstArgument, ...;

    Parameters

    selector

    要被调用的方法名

    firstArgument

    参数列表,请传参数的指针地址,支持多个参数

    Return Value

    方法的返回值,如果该方法返回类型为 void,则会返回 nil,如果返回类型为对象,则返回该对象。

  • 调用一个返回值类型为非对象且带参数的 selector,参数类型支持对象和非对象,也没有数量限制。

      CGPoint point = xxx;
      UIEvent *event = xxx;
      BOOL isInside;
      [view qmui_performSelector:@selector(pointInside:withEvent:) withPrimitiveReturnValue:&isInside arguments:&point, &event, nil];
    

    Declaration

    Objective-C

    - (void)qmui_performSelector:(nonnull SEL)selector
        withPrimitiveReturnValue:(nullable void *)returnValue
                       arguments:(nullable void *)firstArgument, ...;

    Parameters

    selector

    要被调用的方法名

    returnValue

    selector 的返回值的指针地址

    firstArgument

    参数列表,请传参数的指针地址,支持多个参数

  • 使用 block 遍历指定 class 的所有成员变量(也即 _xxx 那种),不包含 property 对应的 _property 成员变量,也不包含 superclasses 里定义的变量

    Declaration

    Objective-C

    - (void)qmui_enumrateIvarsUsingBlock:
        (nonnull void (^)(Ivar _Nonnull, NSString *_Nonnull))block;

    Swift

    func qmui_enumrateIvars(_ block: @escaping (Ivar, String) -> Void)

    Parameters

    block

    用于遍历的 block

  • 使用 block 遍历指定 class 的所有成员变量(也即 _xxx 那种),不包含 property 对应的 _property 成员变量

    Declaration

    Objective-C

    + (void)qmui_enumrateIvarsOfClass:(nonnull Class)aClass
                   includingInherited:(BOOL)includingInherited
                           usingBlock:(nonnull void (^)(Ivar _Nonnull,
                                                        NSString *_Nonnull))block;

    Swift

    class func qmui_enumrateIvars(of aClass: AnyClass, includingInherited: Bool, using block: @escaping (Ivar, String) -> Void)

    Parameters

    aClass

    指定的 class

    includingInherited

    是否要包含由继承链带过来的 ivars

    block

    用于遍历的 block

  • 使用 block 遍历指定 class 的所有属性,不包含 superclasses 里定义的 property

    Declaration

    Objective-C

    - (void)qmui_enumratePropertiesUsingBlock:
        (nonnull void (^)(objc_property_t _Nonnull, NSString *_Nonnull))block;

    Swift

    func qmui_enumrateProperties(_ block: @escaping (objc_property_t, String) -> Void)

    Parameters

    block

    用于遍历的 block,如果要获取 property 的信息,推荐用 QMUIPropertyDescriptor。

  • Declaration

    Objective-C

    + (void)qmui_enumratePropertiesOfClass:(nonnull Class)aClass
                        includingInherited:(BOOL)includingInherited
                                usingBlock:
                                    (nonnull void (^)(objc_property_t _Nonnull,
                                                      NSString *_Nonnull))block;

    Swift

    class func qmui_enumrateProperties(of aClass: AnyClass, includingInherited: Bool, using block: @escaping (objc_property_t, String) -> Void)

    Parameters

    aClass

    指定的 class

    includingInherited

    是否要包含由继承链带过来的 property

    block

    用于遍历的 block,如果要获取 property 的信息,推荐用 QMUIPropertyDescriptor。

  • 使用 block 遍历当前实例的所有方法,不包含 superclasses 里定义的 method

    Declaration

    Objective-C

    - (void)qmui_enumrateInstanceMethodsUsingBlock:
        (nonnull void (^)(Method _Nonnull, SEL _Nonnull))block;

    Swift

    func qmui_enumrateInstanceMethods(_ block: @escaping (Method, Selector) -> Void)
  • 使用 block 遍历指定的某个类的实例方法

    Declaration

    Objective-C

    + (void)qmui_enumrateInstanceMethodsOfClass:(nonnull Class)aClass
                             includingInherited:(BOOL)includingInherited
                                     usingBlock:
                                         (nonnull void (^)(Method _Nonnull,
                                                           SEL _Nonnull))block;

    Swift

    class func qmui_enumrateInstanceMethods(of aClass: AnyClass, includingInherited: Bool, using block: @escaping (Method, Selector) -> Void)

    Parameters

    aClass

    指定的 class

    includingInherited

    是否要包含由继承链带过来的 method

    block

    用于遍历的 block

  • 遍历某个 protocol 里的所有方法

    Declaration

    Objective-C

    + (void)qmui_enumerateProtocolMethods:(nonnull Protocol *)protocol
                               usingBlock:(nonnull void (^)(SEL _Nonnull))block;

    Swift

    class func qmui_enumerateProtocolMethods(_ protocol: Protocol, using block: @escaping (Selector) -> Void)

    Parameters

    protocol

    要遍历的 protocol,例如 \@protocol(xxx)

    block

    遍历过程中调用的 block