2016-08-25 15 views
9

Với giới thiệu open từ khóa trong Swift 3.0 (What is the 'open' keyword in Swift?).Từ khoá 'mở' và phương pháp/thuộc tính có thể ghi đè mở rộng trong tiện ích mở rộng?

Lưu ý: Được giới hạn ở các tiện ích mở rộng trên NSObject các lớp có nguồn gốc hoặc @objc phương pháp/thuộc tính được phân bổ.

Mã Mà kê khai và sử dụng public (class) phương pháp/tài sản trong công tác khuyến trên modules/khuôn khổ đã phá vỡ, như public không còn có nghĩa là 'overridable' bên ngoài xác định mô-đun.

Ví dụ:

public extension UIManagedDocument { 

    public class func primaryDocumentName() -> String { 
     return "Document" 
    } 

    public class func primaryStoreURL() -> URL { 
     let documentsURL = FileManager.default.userDocumentsURL 
     return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL) 
    } 

    public class func primaryModelName() -> String? { 
     return "Model" 
    } 

} 
  • gốc đề nghị (SE-0117) là tập trung vào subclassing và không đề cập đến phần mở rộng.
  • Hiện nay phần mở rộng không hỗ trợ open từ khóa (bạn không thể viết open extension NSObject cũng như open func Method())

Câu hỏi: Có workaround được mở rộng override thể phương pháp cung cấp/tài sản trên modules/khung ?

+0

Đây có phải là thực sự liên quan đến việc mở mới vs chế độ truy cập công cộng? Trừ khi tôi nhầm, bạn không thể ghi đè lên các phương thức được khai báo trong tiện ích mở rộng, không phải trong Swift 2 cũng như trong Swift 3). –

+0

Bạn thích hợp cho các lớp * tinh khiết * nhanh nhưng có thể trên các lớp dẫn xuất NSObject cũng như với các phương thức/thuộc tính được phân bổ '@ objc'. ([Bạn có thể ghi đè giữa các phần mở rộng trong Swift hay không?] (Http://stackoverflow.com/questions/27109006/can-you-override-between-extensions-in-swift-or-not-compiler-seems-confused# 27109202)) – Nocross

+0

Tôi hiểu, cảm ơn. (Có lẽ bạn có thể thêm thông tin đó vào câu hỏi). –

Trả lời

3
  • 'Giao thức định hướng' - tuyên bố giao thức với các phương pháp mong muốn/tài sản sau đó cấu trúc lại tiện ích để giao thức tuân thủ.
  • 'Truyền thống' - triển khai phân lớp trung gian (trừu tượng) với các phương pháp/thuộc tính mong muốn.

Nghị định thư dụ:

protocol PrimaryDocument { 
    static func primaryDocumentName() -> String 

    static func primaryStoreURL() -> URL 

    static func primaryModelName() -> String? 
} 

extension UIManagedDocument : PrimaryDocument { 

    open class func primaryDocumentName() -> String { 
     return "Document" 
    } 

    open class func primaryStoreURL() -> URL { 
     let documentsURL = FileManager.default.userDocumentsURL 
     return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL) 
    } 

    open class func primaryModelName() -> String? { 
     return "Model" 
    } 

} 
6

Trừ khi tôi nhầm lẫn, bạn thể tuyên bố phương pháp khuyến nông như open trong khuôn khổ của bạn nếu bạn chỉ cần bỏ qua public từ khóa trong tờ khai gia hạn:

extension UIManagedDocument { 

    open class func primaryDocumentName() -> String { 
     return "Document" 
    } 
    // ... 
} 

Và sau đó (dành cho NSObject lớp con hoặc @objc thành viên), bạn có thể ghi đè lên các phương pháp trong lớp con tùy chỉnh của bạn trong việc áp dụng chính (hoặc trong bất kỳ mô-đun):

class MyManagedDocument: UIManagedDocument { 

    override class func primaryDocumentName() -> String { 
     return "MyDocument" 
    } 
    // ... 
} 
+0

Tôi không thể bỏ qua từ 'công khai', vì phần mở rộng được khai báo trong mô-đun khác (khung công tác chia sẻ) và lớp con cụ thể được thực hiện trong mục tiêu phụ thuộc (ứng dụng/tiện ích mở rộng). – Nocross

+0

@Nocross: Trên thực tế tôi chỉ thử nghiệm và nó đã làm việc cho tôi. 'mở rộng UIManagedDocument {}' nằm trong một khung công tác và 'lớp MyManagedDocument: UIManagedDocument {}' trong ứng dụng chính. –

+0

Bạn đang làm việc đúng. Nhưng điều làm phiền tôi là theo cách này, chúng tôi đang dựa vào logic 'suy luận' nhanh chóng, ít nhất là không ổn định, cũng như có thể triển khai cụ thể cho các IDE khác nhau – Nocross

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