Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

298
Visualizações
Swift: cambio de método para el método del marco privado y luego invocación de la implementación original

Estoy tratando de cambiar el método de un marco privado para realizar una lógica personalizada y luego me gustaría llamar a la implementación original.

Código:

 class SwizzlingHelper { private struct Constants { static let privateFrameworkClassName = "privateFrameworkClassName" static let swizzledMethodSignature = "swizzledMethodSignature:" } static func swizzle() { let originalSelector = NSSelectorFromString(Constants.swizzledMethodSignature) if let swizzlingClass: AnyClass = NSClassFromString(Constants.privateFrameworkClassName), let originalMethod = class_getInstanceMethod(swizzlingClass.self, originalSelector), let swizzledMethod = class_getClassMethod(SwizzlingHelper.self, #selector(swizzledMethod)) { method_exchangeImplementations(originalMethod, swizzledMethod) } } @objc private static func swizzledMethod(_ arg: String) { // Custom logic // Call original method here - how? } }

He visto varios ejemplos de cómo se realiza el swizzling extendiendo una clase y luego invocando la implementación original llamando a self.originalImplementation() dentro del método swizzled. Dado que esta es una clase de marco privado, no puedo extenderla y, por lo tanto, la clase SwizzlingHelper ayuda a ayudar con el swizzling. Sin embargo, no hay acceso a self dentro del método swizzled para llamar a la implementación original.

Cualquier pista será apreciada. ¡Gracias!

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Realmente no veo el propósito de swizzling en este escenario. Si desea ejecutar la lógica del método original al final, entonces el swizzling no tiene mucho sentido para mí. Parece que podría simplemente pasar un bloque que ejecuta el método del marco después de ejecutar su propia lógica.

Dicho esto, se me ocurrió esto:

 typealias PrivateClassFunction = @convention(c) () -> Void class SwizzingHelper { private let originalMethod: PrivateClassFunction init(forClass: String, methodSignature: String) { let originalSelector: Selector = NSSelectorFromString(methodSignature) guard let swizzledClass = NSClassFromString(forClass), let swizzledMethod = class_getInstanceMethod(SwizzingHelper.self, #selector(run)), let originalMethod = class_getInstanceMethod(swizzledClass.self, originalSelector) else { fatalError() } self.originalMethod = unsafeBitCast(originalMethod, to: PrivateClassFunction.self) method_exchangeImplementations(originalMethod, swizzledMethod) } @objc func run() { print("Running new logic") originalMethod() } }

Pasar el nombre de la clase y las cadenas de selección solo lo hace un poco más flexible en caso de que desee cambiar otros métodos/clases en el futuro. También podría idear alguna forma de hacer que PrivateClassFunction sea más variable (tal como está, querrá ajustar eso para que coincida con los parámetros y el tipo de retorno de los métodos de su marco privado).

Ejecutará el código así:

 let swizzler = SwizzingHelper(forClass: "PrivateClass", methodSignature: "privateClassMethodWithArg:") swizzler.run()
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda