【发布时间】:2021-12-28 22:56:57
【问题描述】:
我目前正在将一个大型项目从 Objective-C 更新到 Swift,但我不知道如何模仿一些逻辑。基本上,我们有一个带有协议的类,该协议定义了几个函数来将任何类转换为自身的 JSON 表示。
该协议如下所示:
#define kJsonSupport @"_jsonCompatible"
#define kJsonClass @"_jsonClass"
@protocol JsonProtocol <NSObject>
- (NSDictionary*)convertToJSON;
- (id)initWithJSON:(NSDictionary* json);
@end
我已经把它改编成这样的 Swift
let JSON_SUPPORT = "_jsonCompatible"
let JSON_CLASS = "_jsonClass"
protocol JsonProtocol
{
func convertToJSON() -> NSDictionary
init(json: NSDictionary)
}
ObjC 类中的一个函数为符合协议的 NSDictionary 中的每个对象运行 convertToJSON 函数,另一个执行相反的操作,使用 init 函数创建对象的实例。输出字典还包含两个键,一个表示相关字典支持此协议 (kJsonSupport: BOOL),另一个包含转换对象的类的 NSString 表示 (kJsonClass: NSString)。然后 reverse 函数使用这两者来确定对象从哪个类转换,以从给定字典中初始化一个新实例。
所有类对于函数本身都是匿名的。我们只知道每个类都符合协议,因此我们可以在其上调用自定义的 init 函数。
这是它在 ObjC 中的样子:
Class rootClass = NSClassFromString(obj[kJsonClass]);
if([rootClass conformsToProtocol:@protocol(JsonProtocol)])
{
Class<JsonProtocol> jsonableClass = (Class<JsonProtocol>)rootClass;
[arr addObject:[[((Class)jsonableClass) alloc] initWithJSON:obj]];
}
但是,我不确定如何在 Swift 中实现这种行为。
这是我最好的尝试。我使用 Swiftify 尝试帮助我到达那里,但编译器也不满意:
let rootClass : AnyClass? = NSClassFromString(obj[JSON_CLASS] as! String)
if let _rootJsonClass = rootClass as? JsonProtocol
{
weak var jsonClass = _rootJsonClass as? AnyClass & JsonProtocol
arr.add(jsonClass.init(json: obj))
}
我在weak var 行和arr.add 行都遇到了几个错误,例如:
非协议、非类类型“AnyClass”(又名“AnyObject.Type”)不能在协议约束类型中使用
'init' 是类型的成员;使用 'type(of: ...)' 来初始化相同动态类型的新对象
参数类型“NSDictionary”不符合预期类型“JsonProtocol”
调用中的无关参数标签“json:”
我有什么方法可以使用自定义协议初始化函数从符合协议的未知类实例化?
【问题讨论】:
-
谈谈将许多类从 Objective C 转换为 Swift 的经验。可以根据经验说,ObjC 开发人员通常必须发挥创造力来填补 ObjC 标准库中的空白。 swift 上不存在这些差距。因此,通常最好重构代码以适应语言的新功能,而不是直接转换。这甚至可以在保持外部接口不变的情况下完成。所以在这种情况下,不要创建自定义 JSON 协议等,而是尝试重构代码以符合
Codable或[String: AnyClass]字典。
标签: ios swift objective-c