Swiftのセレクターのコンフリクトについて

  • 14
    Like
  • 0
    Comment
More than 1 year has passed since last update.

二つのセレクターがコンフリクトする!!

スタンフォードのSwiftのコンテンツで、ちょっと詰まったので記事を書きます。
クロージャーを引数にして以下のような宣言をすると、

    func performOperation(operation: (Double,Double) -> Double){
        if operandStack.count >= 2{
            displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
            enter()
        }
    }

    func performOperation(operation: Double -> Double){
        if operandStack.count >= 1{
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }
 Method 'performOperation' with Objective-C selector 'performOperation:' conflicts with previous declaration with the same Objective-C selector

みたいなエラーが出てきます。performOperationがコンフリクトしているんですね。

http://stackoverflow.com/questions/29457720/compiler-error-method-with-objective-c-selector-conflicts-with-previous-declara

上の記事を参考にしていただければ分かる通り、これは、このセレクタがSwiftから呼ばれた時は大丈夫なんですが、Objective-Cから呼ばれた時はクラッシュするわけですね。
だからエラーが出てます。
なので、Objective-Cから呼ばれないように、片方または両方にprivateをつける。

    private func performOperation(operation: (Double,Double) -> Double){
        if operandStack.count >= 2{
            displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
            enter()
        }
    }

    func performOperation(operation: Double -> Double){
        if operandStack.count >= 1{
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }

これで解決しました。
いかに全体のコードを示しておきます。参考にしていただければと思います。

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var display: UILabel!

    var userIsInTheMiddleOfTypingANumber: Bool = false

    @IBAction func appendDigit(sender: UIButton) {
        let digit = sender.currentTitle!
        if userIsInTheMiddleOfTypingANumber{
            display.text = display.text! + digit
        }else{
            display.text = digit
            userIsInTheMiddleOfTypingANumber = true
        }

        println("digit = \(digit)")
    }

    @IBAction func operate(sender: UIButton) {
        let operation = sender.currentTitle!
        if userIsInTheMiddleOfTypingANumber {
            enter()
        }
        switch operation {
        case "×":performOperation{ $0 * $1}
        case "÷":performOperation{ $1  / $0}
        case "+":performOperation{ $0 + $1}
        case "−":performOperation{ $1 - $0}
        case "√":performOperation{ sqrt($0)}

        default: break
        }
    }
    private func performOperation(operation: (Double,Double) -> Double){
        if operandStack.count >= 2{
            displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
            enter()
        }
    }

    func performOperation(operation: Double -> Double){
        if operandStack.count >= 1{
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }

    var operandStack:Array<Double> = Array<Double>()
    @IBAction func enter() {
        userIsInTheMiddleOfTypingANumber = false
        operandStack.append(self.displayValue)
        println("operandStack = \(operandStack)")
    }

    var displayValue: Double {
        get{
            return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
        }
        set{
            display.text = "\(newValue)"
            userIsInTheMiddleOfTypingANumber = false
        }
    }
}