우선 ... 이것이 유일한 매개 변수입니다. 당신은 이것을 할 필요가 없습니다 (분해하십시오). 예외가 발생하면 서명을 인쇄 할 수 있습니다. 때로는 어떤 종류의 블록이 예상되는지 알려줄 것입니다. 전화가 여러 매개 변수를 포함하는 통증이 특히
다음, 동적 선택기를 호출에 대한 내 생각 ..
당신의 최선의 옵션은 선택기를 수행하지 않는 것입니다 .. 그것은 무엇 당신이 할 수있는
..입니다 do는 인터페이스/확장 포인터를 통한 호출이다. 나는 C++ (Pimpl 관용구의 아이디어 .. COMM 인터페이스도 이와 같이)에서 항상 이것을한다. Swift, Objective-C, Java 등에서도 사용한다.
동일한 인터페이스가있는 프로토콜을 만듭니다. e를 객체로 사용합니다. 해당 프로토콜을 상속하는 확장을 만듭니다. 그런 다음 객체 인스턴스를 해당 확장/인터페이스/프로토콜로 캐스팅합니다.
인터페이스/확장/프로토콜 포인터를 통해 원하는 기능을 호출하십시오.
import UIKit
import MediaPlayer
@objc
protocol MPAProtocol { //Functions must be optional. That way you don't implement their body when you create the extension.
optional func availableRoutes() -> NSArray
optional func discoveryMode() -> Int
optional func fetchAvailableRoutesWithCompletionHandler(completion: (routes: NSArray) -> Void)
optional func name() -> NSString
}
extension NSObject : MPAProtocol { //Needed otherwise casting will fail!
//Do NOT implement the body of the functions from the protocol.
}
사용법 :
#import <Foundation/Foundation.h>
@interface NSObject (MPAVRoutingControllerProtocol)
- (void)fetchAvailableRoutesWithCompletionHandler:(void(^)(NSArray *routes))completion;
@end
@implementation NSObject (MPAVRoutingControllerProtocol)
@end
: 당신이 확장 + 프로토콜을 만드는 대신 브리징 헤더와 함께 할 것 인 경우에
let MPAVRoutingControllerClass: NSObject.Type = NSClassFromString("MPAVRoutingController") as! NSObject.Type
let MPAVRoutingController: MPAProtocol = MPAVRoutingControllerClass.init() as MPAProtocol
MPAVRoutingController.fetchAvailableRoutesWithCompletionHandler! { (routes) in
print(routes);
}
, 당신은 하나의 목표 - C 범주를 다만 것 그런 다음
:
let MPAVRoutingControllerClass: NSObject.Type = NSClassFromString("MPAVRoutingController") as! NSObject.Type
let MPAVRoutingController = MPAVRoutingControllerClass.init()
MPAVRoutingController.fetchAvailableRoutesWithCompletionHandler! { (routes) in
print(routes);
}
마지막으로 프로토콜 삽입을 사용할 수 있다면 다음과 같이 훨씬 쉽게 할 수 있습니다 :
func classFromString(cls: String, interface: Protocol?) -> NSObject.Type? {
guard let interface = interface else {
return NSClassFromString(cls) as? NSObject.Type
}
if let cls = NSClassFromString(cls) {
if class_conformsToProtocol(cls, interface) {
return cls as? NSObject.Type
}
if class_addProtocol(cls, interface) {
return cls as? NSObject.Type
}
}
return nil
}
func instanceFromString<T>(cls: String, interface: Protocol?) -> T? {
return classFromString(cls, interface: interface)?.init() as? T
}
@objc
protocol MPAProtocol {
optional func availableRoutes() -> NSArray
optional func discoveryMode() -> Int
optional func fetchAvailableRoutesWithCompletionHandler(completion: (routes: NSArray) -> Void)
optional func name() -> NSString
}
let MPAVRoutingController: MPAProtocol = instanceFromString("MPAVRoutingController", interface: MPAProtocol.self)!
MPAVRoutingController.fetchAvailableRoutesWithCompletionHandler! { (routes) in
print(routes);
}
요구되는 클로저의 서명을 알고 계십니까? 즉, '객체'가 정확합니까? 전용 함수는 반드시 클로저를 사용하기 때문에 다른 매개 변수를 전달하려고하면 오류가 발생합니다. 또한 swift_performSelector는 객체 매개 변수에 대한 클로저를 허용합니까? 제 3 자의 lib의 의사가 그것에 대해 뭐라고 말합니까? – Gero
미안 해요 나는 방법 서명을 붙여 넣은 줄 알았지 만 다른 뭔가를 붙여 넣어 권자. sig는 reverse engineerred 헤더 파일 (https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks)에 따라'- (void) fetchAvailableRoutesWithCompletionHandler : (id/* block * /) arg1;' /MediaPlayer.framework/MPAVRoutingController.h). 라이브러리에 관해서는, 난 그냥 그것을 스크랩하고 Obj - C에서 응용 프로그램 의이 섹션을 작성하고 나중에 다리를 –
Dang, 그 부분을 해명, 중요한 부분을 설명하지 않습니다.그러나 실제로'(^) (parameterTypes) '부분을 빠뜨린 것으로 가정하면, 블록이 최소한 id (즉, 신속한 AnyObject)를 반환해야하는 것처럼 보입니다. 그 머리글을 다음과 같이 이해할 것입니다 : "'id'를 반환하는 블록을 전달하십시오. 어쩌면'/ * ... */withObject : {() -> AnyObject in/*는 더미 객체를 정의하고/*})'를 시도해보십시오. 일반적으로 설정해야 할 매개 변수를 정확히 모른 채 리버스 엔지니어링 된 메서드를 호출하면 내 경험에 비추어 빠르게 신속하게 남쪽으로 내려갑니다. – Gero