Skip to content

Instantly share code, notes, and snippets.

@aswathr
Created August 9, 2024 15:13
Show Gist options
  • Save aswathr/39739521587729666a4066a9c2f7d201 to your computer and use it in GitHub Desktop.
Save aswathr/39739521587729666a4066a9c2f7d201 to your computer and use it in GitHub Desktop.
Runtime optional protocol conformance research
import Foundation
import CoreText
import SwiftUI
import PlaygroundSupport
typealias VoidHandler = @convention(block) () -> Void
@objc
protocol X {
@objc optional func protoFunc(message: String, completionHandler: @escaping () -> Void)
}
class A: NSObject, X {
@objc
func aFunc(message: String,completionHandler: @escaping () -> Void) {
print(1)
}
@objc
func aFunc(message: String) {
print(2)
}
@objc
func aFunc() {
print(2)
}
@objc
func addClosure(_ closure: @escaping (_ message: NSString, _ completionHandler: () -> Void) -> Void) {
let localBlock: @convention(block) (A, NSString, Any?) -> Void = { (a, message, com) in
print(1234)
let blockPtr = UnsafeRawPointer(Unmanaged<AnyObject>.passUnretained(com as AnyObject).toOpaque())
closure(message, unsafeBitCast(blockPtr, to: VoidHandler.self))
}
class_addMethod(A.self,
NSSelectorFromString("protoFuncWithMessage:completionHandler:"),
imp_implementationWithBlock(localBlock),
"v@:@@?")
}
}
let d = A()
d.addClosure { message, com in
print(message)
com()
}
var mc: UInt32 = 0
let mcPointer = withUnsafeMutablePointer(to: &mc, { $0 })
let mlist = class_copyMethodList(object_getClass(d), mcPointer)!
//
//print("\(mc) methods")
//
//for i in 0...Int(mc) {
// print(String(format: "Method #%d: %s", arguments: [i, sel_getName(method_getName(mlist[i]))]))
//// print(String(cString: method_getTypeEncoding(mlist[i])!))
//}
//d.perform(NSSelectorFromString("protoFuncWithMessage:completionHandler:"), with: "1", with: {})
//d.perform(NSSelectorFromString("protoFuncWithMessage:"), with: NSString(string: "123"))
//d.perform(NSSelectorFromString("protoFunc"))
//#selector(A.aFunc(message:)).description
Task { (d as X).protoFunc?(message: "1234565", completionHandler: { print("completed") }) }
//print(#selector(Y.protoFunc(message:)).description)
//print(#selector(X.protoFunc(message:)).description)
// .protoFunc?(message: "123")
//print(String(cString: method_getTypeEncoding(class_getInstanceMethod(A.self, #selector(A.aFunc(message:)))!)!))
//var i = "123" as NSString
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment