我正在尝试访问iOS私有函数_setApplicationIsOpaque:
(仅供个人使用和测试)。
我已经实现了这段代码:
@_silgen_name("_setApplicationIsOpaque:") func _setApplicationIsOpaque(_ arg1: Bool)
let invokeSetApplicationIsOpaque: (Bool) -> Void = {
// The Objective-C selector for the method.
let selector: Selector = Selector(("_setApplicationIsOpaque:"))
guard case let method = class_getInstanceMethod(UIApplication.self, selector), method != nil else {
fatalError("Failed to look up \(selector)")
}
// Recreation of the method's implementation function.
typealias Prototype = @convention(c) (AnyClass, Selector, Bool) -> Void
let opaqueIMP = method_getImplementation(method)
let function = unsafeBitCast(opaqueIMP, to: Prototype.self)
// Capture the implemenation data in a closure that can be invoked at any time.
return{ arg1 in function(UIApplication.self, selector, arg1)}
}()
extension UIApplication {
func setApplicationIsOpaque(_ isOpaque: Bool) {
return invokeSetApplicationIsOpaque(isOpaque)
}
}
我在以下StackOverflow问题here中找到了访问私有iOS API的方法 在GitHub的Access Private UIKit Function Without Using Bridging Header中。
问题是运行应用程序时出现错误
[UIApplication _setBackgroundStyle:]:无法识别的选择器发送到类0x10437f348
我找到了UIApplication this file的iOS私有API的标题。
答案 0 :(得分:4)
- (void)_setApplicationIsOpaque:(BOOL)arg1;
是实例方法(UIApplication
),如下所示
最初的连字符-
。实例方法被发送到实例
班级本身,而不是班级本身。
Objective-C方法是带有两个隐藏参数的C函数,比较 Messaging 在“Objective-C运行时编程指南”中:
它还传递了两个隐藏的参数:
- 接收对象
- 方法的选择器
对于实例方法,“接收对象”是实例
在您的情况下发送消息的UIApplication
实例。
(对于类方法,它将是类对象)。
因此Swift扩展方法setApplicationIsOpaque
必须将self
传递给闭包,并且必须将其传递给
实现方法的第一个参数:
let invokeSetApplicationIsOpaque: (UIApplication, Bool) -> Void = {
// The Objective-C selector for the method.
let selector = Selector(("_setApplicationIsOpaque:"))
guard case let method = class_getInstanceMethod(UIApplication.self, selector), method != nil else {
fatalError("Failed to look up \(selector)")
}
// Recreation of the method's implementation function.
typealias Prototype = @convention(c) (UIApplication, Selector, Bool) -> Void
let opaqueIMP = method_getImplementation(method)
let function = unsafeBitCast(opaqueIMP, to: Prototype.self)
// Capture the implemenation data in a closure that can be invoked at any time.
return { (appl, arg1) in function(appl, selector, arg1)}
}()
extension UIApplication {
func setApplicationIsOpaque(_ isOpaque: Bool) {
return invokeSetApplicationIsOpaque(self, isOpaque)
}
}
请注意,此处不需要_silgen_name
声明。
@_silgen_name("_setApplicationIsOpaque:") func _setApplicationIsOpaque(_ arg1: Bool)
将Swift函数绑定到全局符号“_setApplicationIsOpaque”, 哪个不存在。如果要添加对该函数的调用
_setApplicationIsOpaque(true)
然后构建应用程序将因链接器错误而失败:
Undefined symbols for architecture x86_64: "__setApplicationIsOpaque:"