Swift는 respondsToSelector에 해당하는 것은 무엇입니까?
나는 구글 검색했지만 그와 동등한 것이 무엇인지 알 수 없었다 respondsToSelector:
.
이것은 내가 찾을 수있는 유일한 것 ( Swift alternatives respondsToSelector :) 이지만 대리인의 존재를 확인하는 경우 내 경우에는 관련이 없습니다. 대리인이 없으며 새로운 API가 있는지 확인하고 싶습니다. 장치에서 실행 중이거나 이전 버전의 API로 폴백하지 않는 경우.
언급했듯이 Swift에서 대부분의 경우 ?
선택적 unwrapper 연산자를 사용하여 필요한 것을 얻을 수 있습니다 . 이를 통해 객체가 존재하고 (아님 nil
) 메소드가 구현 된 경우에만 객체에서 메소드를 호출 할 수 있습니다 .
여전히 필요한 경우 프로토콜의 respondsToSelector:
일부로 여전히 존재 NSObject
합니다.
respondsToSelector:
Swift에서 Obj-C 유형을 호출 하는 경우 예상대로 작동합니다. 자신의 Swift 클래스에서 사용하는 경우 클래스가에서 파생되도록해야합니다 NSObject
.
다음은 선택기에 응답하는지 확인할 수있는 Swift 클래스의 예입니다.
class Worker : NSObject
{
func work() { }
func eat(food: AnyObject) { }
func sleep(hours: Int, minutes: Int) { }
}
let worker = Worker()
let canWork = worker.respondsToSelector(Selector("work")) // true
let canEat = worker.respondsToSelector(Selector("eat:")) // true
let canSleep = worker.respondsToSelector(Selector("sleep:minutes:")) // true
let canQuit = worker.respondsToSelector(Selector("quit")) // false
매개 변수 이름을 생략하지 않는 것이 중요합니다. 이 예에서, Selector("sleep::")
이다 하지 동일 Selector("sleep:minutes:")
.
실제 Swift 교체는 없습니다.
다음과 같은 방법으로 확인할 수 있습니다.
someObject.someMethod?()
someMethod
객체에 정의 된 경우에만 메소드를 호출 someObject
하지만 @objc
메소드를로 선언 한 프로토콜 에만 사용할 수 있습니다 optional
.
Swift는 본질적으로 안전한 언어이므로 메소드를 호출 할 때마다 Swift가 메소드가 있는지 알아야합니다. 런타임 검사가 불가능합니다. 임의의 개체에 대해 임의의 메서드를 호출 할 수는 없습니다.
Obj-C에서도 ARC와 잘 작동하지 않기 때문에 가능하면 이러한 것들을 피해야합니다 (ARC는에 대해 경고를 트리거 함 performSelector:
).
그러나 사용 가능한 API를 확인할 때 인스턴스를 respondsToSelector:
처리하는 경우 Swift를 사용 하더라도 여전히을 사용할 수 있습니다 NSObject
.
@interface TestA : NSObject
- (void)someMethod;
@end
@implementation TestA
//this triggers a warning
@end
var a = TestA()
if a.respondsToSelector("someMethod") {
a.someMethod()
}
Swift 3 구문에 대해 2017 년 3 월 20 일 업데이트 :
선택적인 메소드가 존재하는지 걱정하지 않는다면 delegate?.optionalMethod?()
그렇지 않으면 사용하는 guard
것이 가장 좋은 방법 일 것입니다.
weak var delegate: SomeDelegateWithOptionals?
func someMethod() {
guard let method = delegate?.optionalMethod else {
// optional not implemented
alternativeMethod()
return
}
method()
}
원래 답변 :
"if let"접근 방식을 사용하여 다음과 같은 선택적 프로토콜을 테스트 할 수 있습니다.
weak var delegate: SomeDelegateWithOptionals?
func someMethod() {
if let delegate = delegate {
if let theMethod = delegate.theOptionalProtocolMethod? {
theMethod()
return
}
}
// Reaching here means the delegate doesn't exist or doesn't respond to the optional method
alternativeMethod()
}
NSObjectProtocol의 하위 프로토콜로 프로토콜을 정의 해야하는 것 같습니다 ... 그러면 respondsToSelector 메소드가 표시됩니다
@objc protocol YourDelegate : NSObjectProtocol
{
func yourDelegateMethod(passObject: SomeObject)
}
@objc 만 지정하는 것만으로는 충분하지 않습니다. 또한 실제 대리자는 NSObject의 하위 클래스이므로 Swift에서는 그렇지 않을 수도 있습니다.
테스트하려는 방법이 @objc 프로토콜 ( 선택 사항) 에서 선택적 방법 으로 정의 된 경우 옵션 체인 패턴을 다음과 같이 사용하십시오 .
if let result = object.method?(args) {
/* method exists, result assigned, use result */
}
else { ... }
메소드가 returning으로 선언되면 다음을 Void
사용하십시오.
if object.method?(args) { ... }
보다:
"선택적 체인을 통한 호출 방법"
발췌 : Apple Inc. "Swift Programming Language"
iBooks. https://itun.es/us/jEUH0.l
함수는 Swift의 최고급 유형이므로 프로토콜에 정의 된 선택적 함수가 nil과 비교하여 구현되었는지 확인할 수 있습니다.
if (someObject.someMethod != nil) {
someObject.someMethod!(someArgument)
} else {
// do something else
}
Swift 2에서 Apple은라는 새로운 기능을 도입했습니다.이 기능 API availability checking
은 대체 방법 일 수 있습니다. respondsToSelector:
다음 코드 스 니펫 비교는 WWDC2015 세션 106에서 복사되었습니다 .Swift 의 새로운 기능 도움이 될 것으로 생각되면 필요한 경우 확인하십시오. 더 알고
오래된 접근법 :
@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
if dropButton.respondsToSelector("setSpringLoaded:") {
dropButton.springLoaded = true
}
}
더 나은 접근 방식 :
@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
if #available(OSX 10.10.3, *) {
dropButton.springLoaded = true
}
}
스위프트 3.0
import UIKit
@objc protocol ADelegate : NSObjectProtocol {
@objc optional func hi1()
@objc optional func hi2(message1:String, message2:String)
}
class SomeObject : NSObject {
weak var delegate:ADelegate?
func run() {
// single method
if let methodHi1 = delegate?.hi1 {
methodHi1()
} else {
print("fail h1")
}
// multiple parameters
if let methodHi2 = delegate?.hi2 {
methodHi2("superman", "batman")
} else {
print("fail h2")
}
}
}
class ViewController: UIViewController, ADelegate {
let someObject = SomeObject()
override func viewDidLoad() {
super.viewDidLoad()
someObject.delegate = self
someObject.run()
}
// MARK: ADelegate
func hi1() {
print("Hi")
}
func hi2(message1: String, message2: String) {
print("Hi \(message1) \(message2)")
}
}
swift3
메소드를 호출하려면 아래 코드를 실행하십시오.
self.delegate?.method?()
현재 (Swift 2.1) 세 가지 방법으로 확인할 수 있습니다.
- 사용 respondsToSelector가 @Erik_at_Digit 응답
사용 '?' 의해 답변을 @Sulthan
그리고
as?
연산자 사용하기 :if let delegateMe = self.delegate as? YourCustomViewController { delegateMe.onSuccess() }
Basically it depends on what you are trying to achieve:
- If for example your app logic need to perform some action and the delegate isn't set or the pointed delegate didn't implement the onSuccess() method (protocol method) so option 1 and 3 are the best choice, though I'd use option 3 which is Swift way.
- If you don't want to do anything when delegate is nil or method isn't implemented then use option 2.
I just implement this myself in a project, see code below. As mentions by @Christopher Pickslay it is important to remember that functions are first class citizens and can therefore be treated like optional variables.
@objc protocol ContactDetailsDelegate: class {
optional func deleteContact(contact: Contact) -> NSError?
}
...
weak var delegate:ContactDetailsDelegate!
if let deleteContact = delegate.deleteContact {
deleteContact(contact)
}
another possible syntax by swift..
if let delegate = self.delegate, method = delegate.somemethod{
method()
}
As I started to update my old project to Swift 3.2, I just needed to change the method from
respondsToSelector(selector)
to:
responds(to: selector)
I use guard let else
, so that can do some default stuff if the delegate func is not implemented.
@objc protocol ViewController2Delegate: NSObjectProtocol {
optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnVoid string: String)
optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnString string: String) -> String
}
class ViewController2: UIViewController {
weak var delegate: ViewController2Delegate?
@IBAction func onVoidButtonClicked(sender: AnyObject){
if (delegate != nil && delegate!.respondsToSelector(Selector("viewController2:didSomethingWithStringAndReturnVoid:"))) {
NSLog("ReturnVoid is implemented")
delegate!.viewController2!(self, didSomethingWithStringAndReturnVoid: "dummy")
}
else{
NSLog("ReturnVoid is not implemented")
// Do something by default
}
}
@IBAction func onStringButtonClicked(sender: AnyObject){
guard let result = delegate?.viewController2?(self, didSomethingWithStringAndReturnString: "dummy") else {
NSLog("ReturnString is not implemented")
// Do something by default
return
}
NSLog("ReturnString is implemented with result: \(result)")
}
}
Swift 3:
protocol
@objc protocol SomeDelegate {
@objc optional func method()
}
Object
class SomeObject : NSObject {
weak var delegate:SomeObject?
func delegateMethod() {
if let delegateMethod = delegate?.method{
delegateMethod()
}else {
//Failed
}
}
}
The equivalent is the ? operator:
var value: NSNumber? = myQuestionableObject?.importantMethod()
importantMethod will only be called if myQuestionableObject exists and implements it.
참고URL : https://stackoverflow.com/questions/24167791/what-is-the-swift-equivalent-of-respondstoselector
'Programing' 카테고리의 다른 글
파이썬에서 [] 연산자를 재정의하는 방법은 무엇입니까? (0) | 2020.05.14 |
---|---|
C #에서 CPU 사용량을 얻는 방법? (0) | 2020.05.14 |
플렉스베이스와 너비의 차이점은 무엇입니까? (0) | 2020.05.14 |
엔터티 프레임 워크 : 하나의 데이터베이스, 여러 DbContext. (0) | 2020.05.14 |
express.js에서 app.use와 app.get의 차이점 (0) | 2020.05.14 |