Swift 1.2:从Objc协议实现可选属性

时间:2015-03-31 09:48:14

标签: objective-c swift properties protocols optional

尝试开始使用Swift并在升级到Swift 1.2时遇到以下问题:

@protocol MyObjcProtocol <NSObject>
@optional
@property (copy) NSString *optionalString;
- (void) optionalMethod;
@end

...

class MySwiftClass: NSObject {}

extension MySwiftClass: MyObjcProtocol {
  var optionalString: NSString {
    get { return "Foo" }
    set(newValue) { NSLog("Whatever") }
  }

  // No problem here
  func optionalMethod() {
    NSLog("Bar")
  }
}

实现Objc协议的Swift扩展不能编译:

  

Objective-C方法'optionalString'由getter提供   'optionalString'与可选的require getter冲突   协议'MyObjcProtocol'中的'optionalString'......

     

Objective-C方法'setOptionalString:'由setter提供   'optionalString'与可选的需求设置器冲突   协议'MyObjcProtocol'中的'optionalString'......

很明显,编译器没有意识到我正试图从协议中实现选项,并认为我正在踩着协议的预期ObjC符号。但是,可选的方法 func optionalMethod()编译得很好。从协议中删除@optional并且所有内容都可以正常编译,但并不总是可以或者希望将其作为解决方案。

那么,如何实现呢?试图明确地实现预期的ObjC方法也不起作用:

func optionalString() {
  return "foo"
}
func setOptionalString(newValue: NSString) {
  NSLog("")
}

希望有人可以帮忙!提前谢谢!

3 个答案:

答案 0 :(得分:3)

MyObjcProtocol协议被转换为Swift:

protocol MyObjcProtocol : NSObjectProtocol {

    optional var optionalString: String! { get set }
    optional func optionalMethod()
}

因此,您只需使用String代替NSString

extension MySwiftClass: MyObjcProtocol {
    var optionalString: String {
        get { return "Foo" }
        set(newValue) { NSLog("Whatever") }
    }

    func optionalMethod() {
        NSLog("Bar")
    }
}

答案 1 :(得分:0)

我想问题是协议需要存储属性,因为它指定了copy,但swift扩展不能存储属性

答案 2 :(得分:0)

Objective C中的可选属性等同于Swift中的Optional Type。所以它会像这样翻译:

var optionalString: String! // = false

如果它可以是零:

var optionalString: String? // = nil