具有私有(集合)要求的类绑定协议

问题描述 投票:0回答:1

我有一个

Nameable
协议,打算在
NSManagedObjects
上使用。该协议在其自己的 Swift 包中声明,并打算由许多其他包导入,因此该协议需要公开。我还需要维护协议方法,而不是使用继承的基类。我想使用下面的默认实现来验证我的名字并抛出错误,但似乎没有办法强制开发人员使用
set(_ name: String)
.

import CoreData

public protocol Nameable: NSManagedObject {
    /// The name property of the entity
    /// - Warning: **don't** set this directly, use `set(_ name: String)` to ensure the name is validated
    ///
    /// - Note: This needs to be an `@NSManaged`
    var name: String { get set }
    
    static var defaultName: String { get }
    
    static var maxNameLength: Int { get }
    
    func set(_ name: String) throws
}
public extension Nameable {
    // TODO: Localize
    static var defaultName: String { "Untitled" }
    
    static var maxNameLength: Int { 128 }
    
    func set(_ name: String) throws {
        guard !name.isEmpty else { throw NameError.nameEmpty }
        guard name.count <= Self.maxNameLength else { throw NameError.nameTooLong }
        self.name = name
        try managedObjectContext?.save()
    }
}

public enum NameError: Error {
    case nameEmpty
    case nameTooLong
}

我想像这样使用协议:

@objc(MyObject)
class MyObject: NSManagedObject, Nameable {
  @NSManaged public private(set) var name: String
}

但由于协议是公开的,名称也需要公开设置。我想出的唯一解决方案是“软”(即警告评论,或类似

@NSManaged var unsafeName: String { get set }
的东西)。有什么方法可以实现编译器可以强制执行的预期结果吗?

swift swift-protocols
1个回答
0
投票

你可以有一个内部的

MutableNameable
协议来改进你的 Nameable 协议:

public protocol Nameable: NSManagedObject {
    var name: String { get }
    // ...
}

public extension Nameable {
    // ...
}

internal protocol MutableNameable: Nameable {
    var name: String { get set }
}

extension MutableNameable {
    // ...
}

这会让你拥有:

@objc(MyObject)
class MyObject: NSManagedObject, MutableNameable {
  @NSManaged public internal(set) var name: String
}

MutableNameable
也可以是私有的,但它会强制您在同一个文件中拥有所有符合类型。

© www.soinside.com 2019 - 2024. All rights reserved.