bestsource

@selector() in Swift?

bestsource 2023. 5. 24. 22:16
반응형

@selector() in Swift?

나는 그것을 만들기 위해 노력하고 있습니다.NSTimer안에Swift문제가 좀 있어요

NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)

test()는 같은 클래스의 함수입니다.


편집기에 오류가 표시됩니다.

제공된 인수를 수락하는 'init'에 대한 오버로드를 찾을 수 없습니다.

가 바뀔 때 ㅠㅠㅠㅠㅠselector: test()selector: nil오류가 사라집니다.

시도해 봤습니다.

  • selector: test()
  • selector: test
  • selector: Selector(test())

하지만 아무 것도 작동하지 않고 참고 자료에서 해결책을 찾을 수 없습니다.

Swift 자체는 Selector를 사용하지 않습니다. 목표-C에서 Selector를 사용하는 몇 가지 디자인 패턴은 Swift에서 다르게 작동합니다. (예를 들어 프로토콜 유형에 대한 선택적 체인을 사용하거나is/as 대신 respondsToSelector:그리고 당신이 할 수 있는 모든 곳에서 폐쇄를 사용합니다.performSelector:더 나은 유형/메모리 안전을 위해.)

그러나 타이머와 대상/액션 패턴을 포함하여 셀렉터를 사용하는 많은 중요한 ObjC 기반 API가 여전히 존재합니다.는 Swift를 합니다.SelectorSwift의 ObjC) 대신 자동으로 합니다.SELtype.

Swift 2.2(Xcode 7.3) 이상(Swift 3 / Xcode 8 및 Swift 4 / Xcode 9 포함)에서 다음을 수행합니다.

당신은 수있다니습할성을 할 수 .Selector 에서 스위프트를 합니다.#selector표현.

let timer = Timer(timeInterval: 1, target: object,
                  selector: #selector(MyClass.test),
                  userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
                 for: .touchUpInside)
view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
             with: button, with: otherButton)

이 접근 방식의 좋은 점은 무엇입니까?되므로, "" "" "" "" "" "" " "" 할 수 .#selector식은 실제로 존재하고 실렉터로 사용할 수 있는 클래스/메소드 쌍만 포함합니다(아래 "실렉터 가용성" 참조).또한 함수 유형 이름 지정을 위한 Swift 2.2+ 규칙에 따라 함수 참조를 필요한 만큼만 자유롭게 만들 수 있습니다.

(ObjC의 )@selector()지시, 컴파일러가 있기 때문에.-Wundeclared-selectorcheck는 명명된 선택기만 존재하는지 확인합니다.이 전달하는 는 Swift에 있습니다.#selector존재 여부, 클래스의 구성원 자격 및 형식 서명을 확인합니다.)

다음으로 전달하는 기능 참조에 대해 몇 가지 추가적인 주의 사항이 있습니다.#selector식:

  • 동일한 기본 이름을 가진 여러 함수는 함수 참조(예: 함수 참조)에 대해 앞서 언급한 구문을 사용하여 매개 변수 레이블로 구별할 수 있습니다.insertSubview(_:at:)insertSubview(_:aboveSubview:)하지만 어떤 함수에 매개변수가 없다면, 그것을 명확하게 할 수 있는 유일한 방법은 다음을 사용하는 것입니다.as이 캐스트(예: 예서명형식의수함예▁with()foo as () -> ()foo(_:)).
  • Swift 3.0+에는 속성 getter/setter 쌍에 대한 특수 구문이 있습니다.예를 들어, 다음과 같은 경우var foo: Int사용할 수 있습니다.#selector(getter: MyClass.foo)또는#selector(setter: MyClass.foo).

일반 참고 사항:

에서 작동하지 않는 경우이름 지정: 때때로 선택기를 만들 함수 참조가 없습니다(예: ObjC 런타임에 동적으로 등록된 메서드).이 경우 다음을 구성할 수 있습니다.Selector 문에서: 예:Selector("dynamicMethod:")컴파일러의 유효성 검사를 잃게 되더라도.콜론을 한 ObjC 규칙을 .: 각 입력합니다. 각 매개 변수에 대해 입력합니다.

선택기 가용성:선택기에서 참조하는 메서드는 ObjC 런타임에 노출되어야 합니다.Swift 4에서 ObjC에 노출된 모든 방법은 선언문 앞에 다음을 붙여야 합니다.@objc기다하여 (로 얻을 수 있는 경우가 명시적으로 이전 버전에서는 해당 속성을 무료로 얻을 수 있었지만 이제는 명시적으로 선언해야 합니다.

하세요.private. "" "" "" "" ""가 . 최소한 방법에는internal가시거리

주요 경로:이들은 실렉터와 관련이 있지만 완전히 같지는 않습니다.Swift 3에도 이것들을 위한 특별한 구문이 있습니다: 예를 들어.chris.valueForKeyPath(#keyPath(Person.friends.firstName))자세한 내용은 SE-0062를 참조하십시오.Swift 4에는 더 많은 기능이 있으므로, 적절한 경우 실렉터 대신 올바른 KeyPath 기반 API를 사용해야 합니다.

Selector에 대한 자세한 내용은 Using Swift with CocoaObjective-C의 Objective-C APIs 상호 작용에서 확인할 수 있습니다.

참고: Swift 2.2 이전 버전에서는Selector에적한에 StringLiteralConvertible따라서 선택기를 사용하는 API로 베어 문자열이 전달되는 오래된 코드를 찾을 수 있습니다.당신은에서 " Syntax하여 Xcode를 사용하는 하고자 할 입니다.#selector.

다음은 사용 방법에 대한 간단한 예입니다.SelectorSwift에 대한 강의:

override func viewDidLoad() {
    super.viewDidLoad()

    var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))
    self.navigationItem.rightBarButtonItem = rightButton
}

func method() {
    // Something cool here   
}

문자열로 전달된 메서드가 작동하지 않으면 컴파일 시간이 아닌 런타임에 실패하고 앱이 손상됩니다.조심하세요.

또한 (Swift) 클래스가 Objective-C 클래스에서 하강하지 않는 경우에는 대상 메서드 이름 문자열의 끝에 콜론이 있어야 하며 @objc 속성을 대상 메서드와 함께 사용해야 합니다.

var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))

@objc func method() {
    // Something cool here   
} 

그렇지 않으면 런타임에 "인식되지 않는 선택기" 오류가 발생합니다.

Swift 2.2+ 및 Swift 3 업데이트

새기사를 합니다.#selector식을 사용하면 문자열 리터럴을 사용할 필요가 없으므로 오류가 발생하기 쉽습니다.참조용:

Selector("keyboardDidHide:")

된다

#selector(keyboardDidHide(_:))

참고 항목:신속한 진화 제안

참고(Swift 4.0):

사용하는 경우#selector을 '으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으으@objc

예:

@objc func something(_ sender: UIButton)

스위프트 4.0

아래와 같이 Selector를 생성합니다.

1.같은 합니다.다음과 같은 버튼에 이벤트를 추가합니다.

button.addTarget(self, action: #selector(clickedButton(sender:)), for: UIControlEvents.touchUpInside)

그과 같습니다.

@objc func clickedButton(sender: AnyObject) {

}

미래의 독자들을 위해, 저는 문제를 경험했고 목표를 표시함으로써 발생한 오류를 얻고 있다는 것을 발견했습니다.func사석에서

func 선택기를 참조하여 개체가 호출하려면 공개적으로 보여야 합니다.

다른 답변이 문제를 해결하지 않은 NSTimer와 동일한 문제를 가진 다른 사용자가 있는 경우, NSObject에서 직접 또는 계층 구조(예: 수동으로 생성된 신속한 파일)를 상속하지 않는 클래스를 사용하는 경우,다음과 같이 지정된 경우에도 다른 답변은 작동하지 않습니다.

let timer = NSTimer(timeInterval: 1, target: self, selector: "test", 
                    userInfo: nil, repeats: false)
func test () {}

NSObject에서 클래스를 상속하도록 하는 것 외에 다른 변경 사항이 없이 "Uncognized selector" Error(인식할 수 없는 선택기)를 더 이상 받지 않고 제 논리가 예상대로 작동했습니다.

NSTimer에서 함수로 매개 변수를 전달하려면 다음 솔루션을 사용합니다.

var somethingToPass = "It worked"

let timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "tester:", userInfo: somethingToPass, repeats: false)

func tester(timer: NSTimer)
{
    let theStringToPrint = timer.userInfo as String
    println(theStringToPrint)
}

선택기 텍스트(테스터:)에 콜론을 포함하고 매개 변수는 userInfo에 들어갑니다.

함수는 NSTimer를 매개 변수로 사용해야 합니다.그런 다음 userInfo를 추출하여 전달된 매개 변수를 가져옵니다.

선택기는 목표-C에서 메서드 이름의 내부 표현입니다.Objective-C에서 "@selector(methodName)"는 소스 코드 메서드를 SEL의 데이터 유형으로 변환합니다.Swift에서 @selector 구문을 사용할 수 없으므로(rickster가 해당 지점에 있음) String 개체로 직접 메서드 이름을 지정하거나 String 개체를 Selector 유형으로 전달하여 메서드 이름을 수동으로 지정해야 합니다.다음은 예입니다.

var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 
    action:"logout"
)

또는

var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 
    action:Selector("logout")
)

스위프트 4.1
탭 제스처 샘플과 함께

let gestureRecognizer = UITapGestureRecognizer()
self.view.addGestureRecognizer(gestureRecognizer)
gestureRecognizer.addTarget(self, action: #selector(self.dismiss(completion:)))

// Use destination 'Class Name' directly, if you selector (function) is not in same class.
//gestureRecognizer.addTarget(self, action: #selector(DestinationClass.dismiss(completion:)))


@objc func dismiss(completion: (() -> Void)?) {
      self.dismiss(animated: true, completion: completion)
}

다음에 대한 자세한 내용은 Apple 문서를 참조하십시오.선택기 식

// for swift 2.2
// version 1
buttton.addTarget(self, action: #selector(ViewController.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(ViewController.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 2
buttton.addTarget(self, action: #selector(self.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(self.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 3
buttton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(tappedButton2(_:)), forControlEvents: .TouchUpInside)

func tappedButton() {
  print("tapped")
}

func tappedButton2(sender: UIButton) {
  print("tapped 2")
}

// swift 3.x
button.addTarget(self, action: #selector(tappedButton(_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton) {
  // tapped
}

button.addTarget(self, action: #selector(tappedButton(_:_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton, _ event: UIEvent) {
  // tapped
}

목표-C 선택기

선택기는 메서드를 식별합니다.

//Compile time
SEL selector = @selector(foo);

//Runtime
SEL selector = NSSelectorFromString(@"foo");

예를들면

[object sayHello:@"Hello World"];
//sayHello: is a selector

selector에서 온 단어입니다.Objective-C을 계세그리당그사수있다습니용할을것신은고▁and▁it▁from에서 사용할 수 .Swift전화할 가능성이 있습니다Objective-CSwift에 어떤 할 수 .

Swift 2.2구문:

Selector("foo:")

이 함수이에전로로 Selector매개 변수 "foo")로 지정하면 컴파일 시간이름을 확인할 수 없습니다.따라서 런타임 오류가 발생할 수 있습니다.

unrecognized selector sent to instance

나 뒤에Swift 2.2+구문:

#selector(foo(_:))

Xcode의 자동 완성 기능은 올바른 메서드를 호출하는 데 도움이 됩니다.

Create Refresh control using Selector method.   
    var refreshCntrl : UIRefreshControl!
    refreshCntrl = UIRefreshControl()
    refreshCntrl.tintColor = UIColor.whiteColor()
    refreshCntrl.attributedTitle = NSAttributedString(string: "Please Wait...")
    refreshCntrl.addTarget(self, action:"refreshControlValueChanged", forControlEvents: UIControlEvents.ValueChanged)
    atableView.addSubview(refreshCntrl)

//제어 방법 새로 고침

func refreshControlValueChanged(){
    atableView.reloadData()
    refreshCntrl.endRefreshing()

}

Swift 3.0이 게시되었기 때문에 타겟 Action이 적합하다고 선언하는 것은 훨씬 더 미묘합니다.

class MyCustomView : UIView {

    func addTapGestureRecognizer() {

        // the "_" is important
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyCustomView.handleTapGesture(_:)))
        tapGestureRecognizer.numberOfTapsRequired = 1
        addGestureRecognizer(tapGestureRecognizer)
    }

    // since Swift 3.0 this "_" in the method implementation is very important to 
    // let the selector understand the targetAction
    func handleTapGesture(_ tapGesture : UITapGestureRecognizer) {

        if tapGesture.state == .ended {
            print("TapGesture detected")
        }
    }
}

을 할 때performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval()의 method는(선택기)을다로 .

@objc
For Swift 2.0:
    {  
        //...
        self.performSelector(“performMethod”, withObject: nil , afterDelay: 0.5)
        //...


    //...
    btnHome.addTarget(self, action: “buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    //...

    //...
     NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector : “timerMethod”, userInfo: nil, repeats: false)
    //...

}

@objc private func performMethod() {
…
}
@objc private func buttonPressed(sender:UIButton){
….
}
@objc private func timerMethod () {
….
}

Swift 2.2의 경우 문자열과 셀렉터 이름 대신 '#selector()'를 입력해야 철자 오류 및 충돌 가능성이 더 이상 없습니다.아래는 예입니다.

self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)

작업 문제를 트리거하는 컨트롤을 설정하는 위치를 기록하는 것이 유용할 수 있습니다.

예를 들어, UIBarButtonItem을 설정할 때 viewDidLoad 내에 버튼을 만들어야 했고 그렇지 않으면 인식할 수 없는 선택기 예외가 발생했습니다.

override func viewDidLoad() {
    super.viewDidLoad() 

    // add button
    let addButton = UIBarButtonItem(image: UIImage(named: "746-plus-circle.png"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("addAction:"))
    self.navigationItem.rightBarButtonItem = addButton
}

func addAction(send: AnyObject?) {     
    NSLog("addAction")
}

아래와 같이 Selector를 생성합니다.
1.

UIBarButtonItem(
    title: "Some Title",
    style: UIBarButtonItemStyle.Done,
    target: self,
    action: "flatButtonPressed"
)

2.

flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

@selector 구문이 사라지고 호출할 메서드의 이름을 지정하는 단순 문자열로 대체됩니다.우리 모두가 장황함이 방해가 되었다는 것에 동의할 수 있는 한 가지 영역이 있습니다. 우리가 flatButtonPressed라는 했다면, 는 하나를 이 좋을 입니다: one 론물, 우리 flatButtonPressed, 우리는다중음면좋것다니습하이쓰는나를다는라언했표법선다고이있방목가▁one.

func flatButtonPressed(sender: AnyObject) {
  NSLog("flatButtonPressed")
}

타이머 설정:

    var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, 
                    target: self, 
                    selector: Selector("flatButtonPressed"), 
                    userInfo: userInfo, 
                    repeats: true)
    let mainLoop = NSRunLoop.mainRunLoop()  //1
    mainLoop.addTimer(timer, forMode: NSDefaultRunLoopMode) //2 this two line is optinal

완전하게 하기 위해, 여기 flatButtonPressed가 있습니다.

func flatButtonPressed(timer: NSTimer) {
}

저는 이 답변들 중 많은 것들이 도움이 된다는 것을 알았지만, 버튼이 아닌 것으로 이를 수행하는 방법은 명확하지 않았습니다.UI 레이블에 제스처 인식기를 신속하게 추가하다가 어려움을 겪었기 때문에 위의 모든 내용을 읽은 후 다음과 같이 작업할 수 있었습니다.

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: "labelTapped:")

"Selector"가 다음과 같이 선언된 경우:

func labelTapped(sender: UILabel) { }

공용이며 Selector() 구문을 사용하지 않지만 이를 수행할 수도 있습니다.

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: Selector("labelTapped:"))

#selector를 사용하면 컴파일 시 코드를 확인하여 호출할 메서드가 실제로 존재하는지 확인합니다.더 좋은 것은, 만약 그 방법이 존재하지 않는다면, 당신은 컴파일 오류를 얻게 될 것입니다: Xcode는 당신의 앱 구축을 거부할 것이고, 따라서 다른 가능한 버그의 근원을 잊게 될 것입니다.

override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.rightBarButtonItem =
            UIBarButtonItem(barButtonSystemItem: .Add, target: self,
                            action: #selector(addNewFireflyRefernce))
    }

    func addNewFireflyReference() {
        gratuitousReferences.append("Curse your sudden but inevitable betrayal!")
    }

많은 사람들이 셀렉터가 스위프트로 넘어간 동적으로 호출하는 방법의 객관적인 c 방법이라고 말했듯, 어떤 경우에는 우리가 여전히 그것을 고수하고 있는 것은 아마도 그들이 스위프트에서 일하고 있기 때문일 것입니다.대체할 UI이지만 일부 api에는 스위프트 타이머와 같은 더 빠른 버전이 있습니다. 예를 들어, 사용할 수 있습니다.

class func scheduledTimer(withTimeInterval interval: TimeInterval, 
                                            repeats: Bool, 
                                              block: @escaping (Timer) -> Void) -> Timer

대신에, 당신은 그것을 다음과 같이 부를 수 있습니다.

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true ) {
    ... your test code here
}

또는

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true,
                              block: test)

여기서 메서드 테스트는 타이머 인수를 사용하거나 이름이 지정된 인수를 사용합니다.

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true,
                              block: test(timer:))

또한사야합니다해를 해야 합니다.Timer것은 아니다.NSTimer~하듯이NSTimer name 목표이-c 입니다.

선택기 구문을 호출하는 메서드에서 단순 문자열 이름 지정으로 변경

var timer1 : NSTimer? = nil
timer1= NSTimer(timeInterval: 0.1, target: self, selector: Selector("test"), userInfo: nil, repeats: true)

그런 다음 func test()를 입력합니다.

스위프트 3용

//타이머를 만드는 샘플 코드

Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)

WHERE
timeInterval:- Interval in which timer should fire like 1s, 10s, 100s etc. [Its value is in secs]
target:- function which pointed to class. So here I am pointing to current class.
selector:- function that will execute when timer fires.

func updateTimer(){
    //Implemetation 
} 

repeats:- true/false specifies that timer should call again n again.

스위프트 4의 선택기:

button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside)

빠른 3을 위하여.

let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.test), userInfo: nil, repeats: true)

같은 클래스의 함수 선언:

@objc func test()
{
    // my function
} 

언급URL : https://stackoverflow.com/questions/24007650/selector-in-swift

반응형