2015-02-13 26 views
10

tôi chỉ cập nhật từ nhanh chóng 1,1 đến nhanh chóng 1.2 và được biên dịch Lỗi:Swift 1.2 redeclares phương pháp Objective-C

Method 'setVacation' redeclares Objective-C method 'setVacation:' 

Dưới đây một số mã:

var vacation : Vacation? 
func setVacation(_vacation : Vacation) 
{...} 

Nhưng tôi cần phải gọi setVacation

Có đề xuất nào về cách sửa lỗi này không?

Trả lời

8

Đây là nguyên nhân gây ra bởi sự thay đổi nêu tại Xcode 6.3beta phát hành ghi chú:

Swift now detects discrepancies between overloading and overriding in the Swift type system and the effective behavior seen via the Objective-C runtime. (18391046, 18383574) For example, the following conflict between the Objective-C setter for “property” in a class and the method “setProperty” in its extension is now diagnosed:

class A : NSObject { 
    var property: String = "Hello" // note: Objective-C method 'setProperty:’ 
            // previously declared by setter for 
            // 'property’ here 
} 
extension A { 
    func setProperty(str: String) { } // error: method ‘setProperty’ 
             // redeclares Objective-C method 
             //'setProperty:’ 
} 

Để khắc phục điều này, bạn cần phải thực hiện tất cả các bạn phương pháp chữ ký duy nhất (như Objective-C không cung cấp phương pháp quá tải)

Hoặc không được kế thừa từ NSObject nếu bạn chỉ cần lớp Swift.

+0

Điều này xuất hiện để ngụ ý rằng quá tải phương thức là không thể trong các lớp như UIViewControllers hoặc thực sự bất kỳ lớp nào phân lớp bất kỳ lớp khách quan-c nào. Đúng không? –

+0

Dường như cách giải quyết khác là khai báo riêng tư. Bằng cách đó trình biên dịch sẽ không cố gắng chuyển đổi chúng sang ObjC để không có xung đột. – kwerle

+0

@kwerle Giải pháp tuyệt vời. Đã không nghĩ về điều này trước đây. – Kirsteins

1

Như đã lưu ý bởi @Kirsteins, Swift bây giờ phát hiện các biểu tượng xung đột giữa Swift và Obj-C, và các ký hiệu nhanh chóng có thể gây ra nỗi đau Obj-C. Ngoài các câu trả lời được đưa ra, bạn có thể tránh điều này nói chung bằng cách xác định một nhãn cần thiết cho việc loại bổ sung, thay thế chữ ký cuộc gọi:

import Foundation 

extension NSObject { 
    func foo(d:Double, i:Int) { println("\(d), \(i)") } 
    func foo(withInt d:Int, i:Int) { println("\(d), \(i)") } 
} 

let no = NSObject() 
no.foo(withInt:1, i: 2) 

Ngoài ra mặc dù, và để trả lời câu hỏi trước mắt của bạn, bạn đang cố gắng để áp dụng thành ngữ Obj-C cho Swift. Những gì bạn thực sự muốn, là một trong hai thực hiện didSet (rất có thể), hoặc có thể set:

class WhatIDidLastSummer { 

    var vacation:Bool = false { 
     didSet { 
      // do something 
     } 
    } 

    var staycation:Bool { 
     get { return true } 
     set { 
      // do something 
     } 
    } 

} 
+0

Tôi có vấn đề tương tự nhưng không có trong phương thức setX. Tôi đang làm bài tập từ khóa học iTune của Đại học Stanford. Khi tôi chuyển đổi sang Swift 1.2, một số mã được sử dụng để biên dịch ngừng biên dịch. Phương thức là performOperation. –

+0

2 phương pháp có chữ ký khác nhau. "func performOperation (hoạt động: (Double, Double) -> Double)", và: "func performOperation (hoạt động: (Double) -> Double)". Cái đầu tiên không nhận được lỗi, nhưng cái thứ hai thì không. (Lỗi là: "Phương thức" performOperation 'redeclares Objective-C method' performOperation: '"). Tôi có thể thấy "performOperation" là một phương pháp ObjC chính hãng ở đâu đó ... nhưng tại sao phương pháp đầu tiên không sinh ra lỗi? –

+0

(Không biết ngữ cảnh của bạn), đó là vì mã cụ thể đó có nguồn gốc từ NSObject hoặc được đánh dấu là @objc và Obj-C không hỗ trợ quá tải hàm/phương thức, ngay cả với các chữ ký kiểu khác nhau. TL; DR, nó sẽ hoạt động tốt trong môi trường Swift-only, nhưng Obj-C không thể sử dụng nó, và đoạn mã có nguồn gốc từ Obj-C, hoặc có sẵn cho Obj-C. –

4

Cappy: Đối với các vấn đề Standford tôi đã sử dụng đơn giản này, bởi vì nó trông giống như Xcode Beta chỉ đơn giản nói rằng các hoạt động: (Double, Double) -> Double giống như thao tác: Double -> Double, tôi không biết đó có phải là lỗi hay không ...

Nhưng mã bên dưới hoạt động, nhưng là NOT clean :(

func performOperation(r:String? = "2", 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() 
    } 
} 
Các vấn đề liên quan