NSObject

@_spi(FW) extension NSObject
extension NSObject: WrapperCompatible

Observer

  • 监听对象某个属性,对象释放时自动移除监听,添加多次执行多次

    Declaration

    Swift

    @discardableResult
    public func fw_observeProperty(_ property: String, block: @escaping (Any, [NSKeyValueChangeKey : Any]) -> Void) -> NSObjectProtocol

    Parameters

    property

    属性名称

    block

    目标句柄,block参数依次为object、优化的change字典(不含NSNull)

    Return Value

    监听者

  • 监听对象某个属性,对象释放时自动移除监听,添加多次执行多次

    Declaration

    Swift

    @discardableResult
    public func fw_observeProperty(_ property: String, target: AnyObject?, action: Selector) -> NSObjectProtocol

    Parameters

    property

    属性名称

    target

    目标对象

    action

    目标动作,action参数依次为object、优化的change字典(不含NSNull)

    Return Value

    监听者

  • 手工移除某个属性指定监听

    Declaration

    Swift

    public func fw_unobserveProperty(_ keyPath: AnyHashable, target: AnyObject? = nil, action: Selector? = nil)

    Parameters

    keyPath

    属性keyPath

    target

    目标对象,值为nil时移除所有对象(同UIControl)

    action

    目标动作,值为nil时移除所有动作(同UIControl)

  • 手工移除某个属性指定监听

    Declaration

    Swift

    @discardableResult
    public func fw_unobserveProperty(observer: Any) -> Bool

    Parameters

    observer

    监听者

  • 手工移除所有属性所有监听

    Declaration

    Swift

    public func fw_unobserveAllProperties()
  • 手工添加指定KeyPath监听,对象释放时自动移除监听,添加多次执行多次

    Declaration

    Swift

    @discardableResult
    public func fw_addObservation(_ observation: NSKeyValueObservation, keyPath: AnyHashable? = nil, target: AnyObject? = nil, action: Selector? = nil) -> NSObjectProtocol

    Parameters

    observation

    监听对象

    keyPath

    属性keyPath

    target

    目标对象

    action

    目标动作

    Return Value

    监听者

  • 手工移除指定KeyPath监听

    Declaration

    Swift

    @discardableResult
    public func fw_removeObservation(_ observation: NSKeyValueObservation) -> Bool

    Parameters

    observation

    监听对象

    Return Value

    是否移除成功

Class

  • 获取指定类的metaClass

    Declaration

    Swift

    public static func fw_metaClass(_ clazz: Any?) -> AnyClass?

    Parameters

    clazz

    支持AnyClass|NSObject对象

    Return Value

    参数为AnyClass时,返回metaClass;参数为NSObject对象时,返回NSObject类

  • 获取指定类的所有子类

    Declaration

    Swift

    public static func fw_allSubclasses(_ clazz: AnyClass) -> [AnyClass]
  • 获取类方法列表(含父类直至NSObject),支持meta类(objc_getMetaClass)

    Declaration

    Swift

    public static func fw_classMethods(_ clazz: AnyClass) -> [String]

    Parameters

    clazz

    指定类

    Return Value

    方法列表

  • 获取类属性列表(含父类直至NSObject),支持meta类(objc_getMetaClass)

    Declaration

    Swift

    public static func fw_classProperties(_ clazz: AnyClass) -> [String]

    Parameters

    clazz

    指定类

    Return Value

    属性列表

  • 获取类Ivar列表(含父类直至NSObject),支持meta类(objc_getMetaClass)

    Declaration

    Swift

    public static func fw_classIvars(_ clazz: AnyClass) -> [String]

    Parameters

    clazz

    指定类

    Return Value

    Ivar列表

Property

  • 读取关联对象,key为字符串,一般可使用#function

    Declaration

    Swift

    public static func fw_getAssociatedObject(_ object: Any, key: String) -> Any?
  • 设置关联对象,key为字符串,一般可使用#function

    Declaration

    Swift

    public static func fw_setAssociatedObject(_ object: Any, key: String, value: Any?, policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

Mirror

  • 执行任意对象的反射属性句柄(含父类)

    Declaration

    Swift

    public static func fw_mirrorMap(_ object: Any, block: (String, Any) throws -> Void) rethrows
  • 获取任意对象的反射字典(含父类直至NSObject),不含nil值

    Declaration

    Swift

    public static func fw_mirrorDictionary(_ object: Any?) -> [String : Any]

Exchange

  • 交换类实例方法。复杂情况可能会冲突

    Declaration

    Swift

    @discardableResult
    public static func fw_exchangeInstanceMethod(
        _ originalSelector: Selector,
        swizzleMethod: Selector
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    swizzleMethod

    交换方法

    Return Value

    是否成功

  • 交换类静态方法。复杂情况可能会冲突

    Declaration

    Swift

    @discardableResult
    public static func fw_exchangeClassMethod(
        _ originalSelector: Selector,
        swizzleMethod: Selector
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    swizzleMethod

    交换方法

    Return Value

    是否成功

  • 交换类实例方法为block实现。复杂情况可能会冲突

    swizzleBlock示例:

    ^(__unsafe_unretained UIViewController *selfObject, BOOL animated){ ((void(*)(id, SEL, BOOL))objc_msgSend)(selfObject, swizzleSelector, animated); }
    

    Declaration

    Swift

    @discardableResult
    public static func fw_exchangeInstanceMethod(
        _ originalSelector: Selector,
        swizzleMethod: Selector,
        block: Any
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    swizzleMethod

    交换方法

    block

    实现block

    Return Value

    是否成功

  • 交换类静态方法为block实现。复杂情况可能会冲突

    Declaration

    Swift

    @discardableResult
    public static func fw_exchangeClassMethod(
        _ originalSelector: Selector,
        swizzleMethod: Selector,
        block: Any
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    swizzleMethod

    交换方法

    block

    实现block

    Return Value

    是否成功

  • 生成原始方法对应的随机交换方法

    Declaration

    Swift

    public static func fw_exchangeSwizzleSelector(
        _ selector: Selector
    ) -> Selector

    Parameters

    selector

    原始方法

    Return Value

    交换方法

Swizzle

  • 通用swizzle替换方法为block实现,支持类和对象,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Swift实现代码示例:

    NSObject.fw_swizzleInstanceMethod(UIViewController.self, selector: NSSelectorFromString("viewDidLoad")) { targetClass, originalCMD, originalIMP in
        let swizzleIMP: @convention(block)(UIViewController) -> Void = { selfObject in
            let originalMSG = unsafeBitCast(originalIMP(), to: (@convention(c)(UIViewController, Selector) -> Void).self)
            originalMSG(selfObject, originalCMD)
    
            // ...
        }
        return unsafeBitCast(swizzleIMP, to: AnyObject.self)
    }
    

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleMethod(
        _ target: Any?,
        selector: Selector,
        identifier: String? = nil,
        block: @escaping (AnyClass, Selector, @escaping () -> IMP) -> Any
    ) -> Bool

    Parameters

    target

    目标类或对象

    selector

    原始方法

    identifier

    唯一标识,有值且相同时仅执行一次,默认nil

    block

    实现句柄

    Return Value

    是否成功

  • 使用swizzle替换类实例方法为block实现,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Swift实现代码示例:

    NSObject.fw_swizzleInstanceMethod(UIViewController.self, selector: NSSelectorFromString("viewDidLoad")) { targetClass, originalCMD, originalIMP in
        let swizzleIMP: @convention(block)(UIViewController) -> Void = { selfObject in
            let originalMSG = unsafeBitCast(originalIMP(), to: (@convention(c)(UIViewController, Selector) -> Void).self)
            originalMSG(selfObject, originalCMD)
    
            // ...
        }
        return unsafeBitCast(swizzleIMP, to: AnyObject.self)
    }
    

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleInstanceMethod(
        _ originalClass: AnyClass,
        selector: Selector,
        identifier: String? = nil,
        block: @escaping (AnyClass, Selector, @escaping () -> IMP) -> Any
    ) -> Bool

    Parameters

    originalClass

    原始类

    selector

    原始方法

    identifier

    唯一标识,默认nil

    block

    实现句柄

    Return Value

    是否成功

  • 使用swizzle替换类静态方法为block实现,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleClassMethod(
        _ originalClass: AnyClass,
        selector: Selector,
        identifier: String? = nil,
        block: @escaping (AnyClass, Selector, @escaping () -> IMP) -> Any
    ) -> Bool

    Parameters

    originalClass

    原始类

    selector

    原始方法

    identifier

    唯一标识,默认nil

    block

    实现句柄

    Return Value

    是否成功

  • 使用swizzle替换对象实例方法为block实现,identifier相同时仅执行一次。结合isSwizzleInstanceMethod使用

    Declaration

    Swift

    @discardableResult
    public func fw_swizzleInstanceMethod(
        _ originalSelector: Selector,
        identifier: String = "",
        block: @escaping (AnyClass, Selector, @escaping () -> IMP) -> Any
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    identifier

    唯一标识,默认空字符串

    block

    实现句柄

    Return Value

    是否成功

  • 判断对象是否使用swizzle替换过指定identifier实例方法。结合swizzleInstanceMethod使用

    因为实际替换的是类方法,为了防止影响该类其它对象,需先判断该对象是否替换过,仅替换过才执行自定义流程

    Declaration

    Swift

    public func fw_isSwizzleInstanceMethod(
        _ originalSelector: Selector,
        identifier: String = ""
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    identifier

    唯一标识,默认空字符串

    Return Value

    是否替换

NSObject+SwizzleStore

  • 通用swizzle替换方法为block实现,支持类和对象,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Swift实现代码示例:

    NSObject.fw_swizzleMethod(
        UIViewController.self,
        selector: #selector(UIViewController.viewDidLoad)
    ) { (store: SwizzleStore
         <@convention(c) (UIViewController, Selector) -> Void,
         @convention(block) (UIViewController) -> Void>) in {
        store.original($0, store.selector)
        // ...
    }}
    

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleMethod<MethodSignature, SwizzleSignature>(
        _ target: Any?,
        selector: Selector,
        identifier: String? = nil,
        methodSignature: MethodSignature.Type = MethodSignature.self,
        swizzleSignature: SwizzleSignature.Type = SwizzleSignature.self,
        block: @escaping (SwizzleStore<MethodSignature, SwizzleSignature>) -> SwizzleSignature
    ) -> Bool

    Parameters

    target

    目标类或对象

    selector

    原始方法

    identifier

    唯一标识,有值且相同时仅执行一次,默认nil

    methodSignature

    原始方法签名,示例:(@convention© (AnyObject, Selector) -> String).self

    swizzleSignature

    交换方法签名,示例:(@convention(block) (AnyObject) -> String).self

    block

    实现句柄,示例:{ store in { selfObject in return store.original(selfObject, store.selector) } }

    Return Value

    是否成功

  • 使用swizzle替换类实例方法为block实现,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Swift实现代码示例:

    NSObject.fw_swizzleInstanceMethod(
        UIViewController.self,
        selector: #selector(UIViewController.viewDidLoad),
        methodSignature: (@convention(c) (UIViewController, Selector) -> Void).self,
        swizzleSignature: (@convention(block) (UIViewController) -> Void).self
    ) { store in { selfObject in
        store.original(selfObject, store.selector)
        // ...
    }}
    

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleInstanceMethod<MethodSignature, SwizzleSignature>(
        _ originalClass: AnyClass,
        selector: Selector,
        identifier: String? = nil,
        methodSignature: MethodSignature.Type = MethodSignature.self,
        swizzleSignature: SwizzleSignature.Type = SwizzleSignature.self,
        block: @escaping (SwizzleStore<MethodSignature, SwizzleSignature>) -> SwizzleSignature
    ) -> Bool

    Parameters

    originalClass

    原始类

    selector

    原始方法

    identifier

    唯一标识,默认nil

    methodSignature

    原始方法签名,示例:(@convention© (AnyObject, Selector) -> String).self

    swizzleSignature

    交换方法签名,示例:(@convention(block) (AnyObject) -> String).self

    block

    实现句柄,示例:{ store in { selfObject in return store.original(selfObject, store.selector) } }

    Return Value

    是否成功

  • 使用swizzle替换类静态方法为block实现,identifier有值且相同时仅执行一次。复杂情况不会冲突,推荐使用

    Declaration

    Swift

    @discardableResult
    public static func fw_swizzleClassMethod<MethodSignature, SwizzleSignature>(
        _ originalClass: AnyClass,
        selector: Selector,
        identifier: String? = nil,
        methodSignature: MethodSignature.Type = MethodSignature.self,
        swizzleSignature: SwizzleSignature.Type = SwizzleSignature.self,
        block: @escaping (SwizzleStore<MethodSignature, SwizzleSignature>) -> SwizzleSignature
    ) -> Bool

    Parameters

    originalClass

    原始类

    selector

    原始方法

    identifier

    唯一标识,默认nil

    methodSignature

    原始方法签名,示例:(@convention© (AnyObject, Selector) -> String).self

    swizzleSignature

    交换方法签名,示例:(@convention(block) (AnyObject) -> String).self

    block

    实现句柄,示例:{ store in { selfObject in return store.original(selfObject, store.selector) } }

    Return Value

    是否成功

  • 使用swizzle替换对象实例方法为block实现,identifier相同时仅执行一次。结合isSwizzleInstanceMethod使用

    Declaration

    Swift

    @discardableResult
    public func fw_swizzleInstanceMethod<MethodSignature, SwizzleSignature>(
        _ originalSelector: Selector,
        identifier: String = "",
        methodSignature: MethodSignature.Type = MethodSignature.self,
        swizzleSignature: SwizzleSignature.Type = SwizzleSignature.self,
        block: @escaping (SwizzleStore<MethodSignature, SwizzleSignature>) -> SwizzleSignature
    ) -> Bool

    Parameters

    originalSelector

    原始方法

    identifier

    唯一标识,默认空字符串

    methodSignature

    原始方法签名,示例:(@convention© (AnyObject, Selector) -> String).self

    swizzleSignature

    交换方法签名,示例:(@convention(block) (AnyObject) -> String).self

    block

    实现句柄,示例:{ store in { selfObject in return store.original(selfObject, store.selector) } }

    Return Value

    是否成功

ExtendCustomModelType

  • Finds the internal object in object as the designatedPath specified designatedPath is a string like result.data.orderInfo, which each element split by . represents key of each layer

    Declaration

    Swift

    public static func getInnerObject(inside object: Any?, by designatedPath: String?) -> Any?

NSObject+Theme

  • 订阅主题通知并指定主题上下文(如vc|view),非UITraitEnvironment等需指定后才能响应系统主题

    Declaration

    Swift

    public weak var fw_themeContext: (NSObject & UITraitEnvironment)? { get set }
  • 添加iOS13主题改变通知回调,返回订阅唯一标志,需订阅后才生效

    Declaration

    Swift

    @discardableResult
    public func fw_addThemeListener(_ listener: @escaping (ThemeStyle) -> Void) -> String
  • iOS13根据订阅唯一标志移除主题通知回调

    Declaration

    Swift

    public func fw_removeThemeListener(_ identifier: String)
  • iOS13移除所有主题通知回调,一般用于cell重用

    Declaration

    Swift

    public func fw_removeAllThemeListeners()
  • iOS13主题改变包装器钩子,如果父类有重写,记得调用super,需订阅后才生效

    Declaration

    Swift

    open func themeChanged(_ style: ThemeStyle)
  • iOS13主题改变渲染钩子,如果父类有重写,记得调用super,需订阅后才生效

    Declaration

    Swift

    open func renderTheme(_ style: ThemeStyle)

NSObject+Appearance

  • 从 appearance 里取值并赋值给当前实例,通常在对象的 init 里调用。支持的属性需标记为\@objc dynamic才生效

    Declaration

    Swift

    public func fw_applyAppearance()

NSObject+Foundation

  • 同一个token仅执行一次闭包,全局范围

    Declaration

    Swift

    public static func fw_dispatchOnce(
        _ token: AnyHashable,
        closure: @escaping () -> Void
    )
  • 延迟delay秒后主线程执行,返回可取消的block,全局范围

    Declaration

    Swift

    @discardableResult
    public static func fw_performBlock(
        _ block: @escaping () -> Void,
        afterDelay delay: TimeInterval
    ) -> Any
  • 延迟delay秒后后台线程执行,返回可取消的block,全局范围

    Declaration

    Swift

    @discardableResult
    public static func fw_performBlock(
        inBackground block: @escaping () -> Void,
        afterDelay delay: TimeInterval
    ) -> Any
  • 延迟delay秒后指定线程执行,返回可取消的block,全局范围

    Declaration

    Swift

    @discardableResult
    public static func fw_performBlock(
        _ block: @escaping () -> Void,
        on queue: DispatchQueue,
        afterDelay delay: TimeInterval
    ) -> Any
  • 取消指定延迟block,全局范围

    Declaration

    Swift

    public static func fw_cancelBlock(_ block: Any)
  • 同步方式执行异步block,阻塞当前线程(信号量),异步block必须调用completionHandler,全局范围

    Declaration

    Swift

    public static func fw_syncPerform(
        asyncBlock: @escaping (@escaping () -> Void) -> Void
    )
  • 重试方式执行异步block,直至成功或者次数为0(小于0不限)或者超时(小于等于0不限),完成后回调completion。block必须调用completionHandler,参数示例:重试4次|超时8秒|延迟2秒

    Declaration

    Swift

    public static func fw_performBlock(
        _ block: @escaping (@escaping (Bool, Any?) -> Void) -> Void,
        completion: @escaping (Bool, Any?) -> Void,
        retryCount: Int,
        timeoutInterval: TimeInterval,
        delayInterval: @escaping (Int) -> TimeInterval,
        isCancelled: (() -> Bool)? = nil
    )
  • 执行轮询block任务,返回任务Id可取消

    Declaration

    Swift

    @discardableResult
    public static func fw_performTask(_ task: @escaping () -> Void, start: TimeInterval, interval: TimeInterval, repeats: Bool, async: Bool) -> String
  • 指定任务Id取消轮询任务

    Declaration

    Swift

    public static func fw_cancelTask(_ taskId: String)