我有一个用于NSManagedObjects
的Nameable
协议。此协议在其自己的Swift包中声明,并打算由许多其他包导入,因此协议需要是公共的。我还需要维护协议方法,而不是使用具有继承的基类。我希望使用以下默认实现验证我的名称并抛出错误,但是似乎没有办法强制开发人员使用set(_ name: String)
。
import CoreData
public protocol Nameable: NSManagedObject {
/// The name property of the entitiy
/// - 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
}
但是由于协议是公共的,name也需要是可公开设置的。我提出的唯一解决方案是“软”(即警告注解,或类似@NSManaged var unsafeName: String { get set }
的东西)。有什么方法可以实现编译器可以强制执行的预期结果吗?
1条答案
按热度按时间m4pnthwp1#
您可以使用内部
MutableNameable
协议来细化您的可命名协议:这将允许您:
MutableNameable
也可以是私有的,但它会强制您在同一个文件中包含所有符合的类型。