2015-02-05 18 views
6

Tôi đang làm việc với một Observer API (ObserverSet) có chức năng sau:nhanh chóng - một phần ứng dụng chức năng với Generics

public func add<T: AnyObject>(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry<Parameters> 

Nó chỉ đơn giản đăng ký một object sau đó gọi phương thức dụ f trên object khi thông báo kích hoạt

Trong một người quản lý của tôi, tôi cần phải ẩn chức năng trước đó với một trong số của tôi để tôi có thể buộc một người quan sát gọi một chức năng định sẵn được thực hiện thông qua giao thức.

Dưới đây là những gì tôi đã làm như vậy cho đến nay:

@objc protocol Observer : NSObjectProtocol { 
    func observe(param: String) -> Void 
} 

func addObserver<T: AnyObject where T: Observer>(observer: T) { 
    let f: T -> String -> Void = observer.dynamicType.observe 
    entries.addObserver(observer, f) 
} 

Thật không may, tôi đã được lỗi sau hiển thị Partial application of generic method is not allowed

Tôi đã tìm thấy một workaround có thể ở đâu đó trên SO trông như thế:

let f: T -> String -> Void = { (obs: T) in obs.dynamicType.observe(obs) } 

Nhưng dòng mã này khiến XCode tôi điên với một số Segmentation Fault: 11 trên biên soạn (và Communication interrupted với Playground ..)

Có cách giải quyết nào cho những gì tôi đang cố gắng làm không?

+0

Điều gì xảy ra nếu bạn khai báo giao thức của mình dưới dạng giao thức Swift thuần túy thay vì làm giảm giao thức thành giao thức objc? – augustzf

+0

Lỗi chính xác tương tự. Nếu tôi cũng loại bỏ việc thực hiện 'NSObjectProtocol' tôi nhận được' lỗi: 'T' không phải là một kiểu con của 'inout T'' – Yaman

Trả lời

4

tôi đã không kiểm tra nhưng bạn có thể thử:

@objc protocol Observer : NSObjectProtocol { 
    func observe(param: String) -> Void 
} 

func addObserver<T: AnyObject where T: Observer>(observer: T) { 
    let f: T -> String -> Void = { ($0 as AnyObject).observe } 
    entries.addObserver(observer, f) 
} 

Ít nhất, điều này biên dịch vì AnyObject có tất cả các phương pháp từ ObjC - bao gồm @objc - lớp/giao thức, như ImplicitlyUnwrappedOptional.

Vì vậy, đây biên dịch:

let str = NSString(string: "test") 
(str as AnyObject).observe("foo") 

Tất nhiên điều này gây ra lỗi runtime vì NSString không có phương pháp observe(_:). Tuy nhiên, trong trường hợp của bạn, T được đảm bảo là Observer, nó sẽ hoạt động.

+0

Yay! Diễn viên đó đã làm điều đó. Nhưng tôi không hiểu tại sao tôi có một lỗi phân đoạn mà không có nó? '' đã nói rằng 'T' là một' AnyObject' phải không? Lỗi có thể xảy ra? – Yaman

+0

Cuộc xung đột Segfault chính nó chắc chắn là một lỗi. Nhưng tôi không chắc chắn về yêu cầu của đúc, nó có thể là một giới hạn ngôn ngữ. Nếu vậy, trình biên dịch phải báo cáo thông báo lỗi tương ứng. – rintaro

Các vấn đề liên quan