我已经看到了许多有关在Swift中实现Obj-C协议的问题,但反过来却没那么多,而且我还没有具体看到。
我正在使用混合的Obj-C / Swift代码库。我有一个Swift协议定义如下:
NamedItem.swift
@objc protocol NamedItem {
var name: String { get }
}
我有一个现有的Objective-C类,该类目前具有自己的name
属性:
MyObjcClass.h
@interface MyObjcClass : NSObject
@property (nonatomic, strong, readonly) NSString* name;
@end
我还有其他几个具有name
属性的类,因此显然我想将它们与协议相关联,而不是将类型转换为一堆不同的类型。现在,如果我尝试将Obj-C类从具有自己的属性切换为实现Swift协议:
MyObjcClass.h
@protocol MyObjcProtocol
@property (nonatomic, strong, readonly) NSString* place;
@end
@interface MyObjcClass : NSObject
@end
MyObjcClass.m
@interface MyObjcClass () <NamedItem>
@end
@implementation MyObjcClass
@synthesize name = _name;
@synthesize place = _place;
@end
在我的其他Objective-C类中效果很好,但是如果我尝试从Swift类中访问名称属性
:SomeSwiftClass.swift
let myObj = MyObjcClass()
myObj.name // error
myObj.place // no problem
我收到以下错误:
“ MyObjcClass”类型的值没有成员“名称”
如果我没有从@property
中删除现有的MyObjcClass.h
声明,而忽略了@synthesize
语句,那么一切都将正确构建。这似乎很奇怪和错误-如果您从Obj-C类采用Objc-C协议,则不必重新定义属性,只需使用@synthesize
语句即可。
我已经尝试过用我能想到的每一种方式定义Swift协议,并且能够找到建议,但是我一直无法解决这个问题。
那么,在Objective-C类中实现Swift协议属性(也许专门是只读属性)的正确方法是什么,以便另一个Swift类可以访问它?我真的必须在Obj-C标头中重新声明该属性吗?我知道我总是可以放弃它,只是在Objective-C中定义协议,但是... Swift是未来! (或类似的东西...)
答案 0 :(得分:2)
// MyObjcClass.m
@interface MyObjcClass () <NamedItem>
@end
该声明对Swift不可见。将协议一致性子句<NamedItem>
移到类的头文件中。
// MyObjCClass.h
// Required for visibility of the protocol
#import "MyProject-Swift.h"
@interface MyObjcClass : NSObject <NamedItem>
@end
正如您评论的那样,Swift编译器仍然说myObj
没有属性name
。这很奇怪。请注意
let myObj = MyObjcClass() as NamedItem
myObj.name
编译良好。
答案 1 :(得分:1)
好吧,设法从JoshCaswell和this博客文章中获得了一些建议,并找到了可行的解决方案。
现在的类如下:
NamedItem.swift
@objc protocol NamedObject {
var name: String { get }
}
MyObjcClass.h
@protocol NamedItem;
@interface MyObjcClass : NSObject
- (id<NamedItem>)asNamedItem;
@end
MyObjcClass.m
@interface MyObjcClass () <NamedItem>
@synthesize name = _name;
- (id<NamedItem>)asNamedItem
{
return self;
}
@end
用法现在看起来像:
SomeSwiftClass.swift
let myObj = MyObjcClass()
myObj.asNamedItem.name
不像我所希望的那样干净利落,但是它比一堆警告或承认失败并在Objective-C中重写协议要好。 (我不知道,也许不是。。。但这是我的追求。)
希望对别人有帮助。