我正在尝试慢慢地从Obj-C迁移到Swift。我的第一步是将小型、简单的方法迁移到Swift扩展,所以我决定尝试迁移didRegsterForRemote teNotiations
但这并不起作用,因为它认为该方法是在我的Objective-C代码中的其他地方实现的。事实并非如此。
我使用的是Xcode 7.3(7D175)
以下是一些复制步骤:
>
AppServer ate-Extension.swift
。这也创建了一个桥接头文件。#导入AppServer. h
到Briding头文件。转到空的Swift文件并输入:
extension AppDelegate {
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}
}
这会导致编译器投诉:
具有Objective-C选择器的方法“application(\uURegisterForremotentificationsWithDeviceToken:)”应用程序:DidRegisterForremotentificationsWithDeviceToken:”与具有相同Objective-C选择器公共函数应用程序的上一个声明冲突(应用程序:UIApplication,DidRegisterForremotentificationsWithDeviceToken:NSData){^u ObjC.AppDelegate:38:17:注意:“application”之前在这里声明了public func application(application:UIApplication,didRegisterforremotentificationswithDeviceToken deviceToken:NSData)
我做错了什么?
编辑:我尝试过的一些建议:
将覆盖添加到方法声明中,使其读取覆盖公共
这将返回以下错误(除原始错误外)
错误:方法不会覆盖其超类覆盖公共func应用程序的任何方法(应用程序:UIApplication,didRegsterForRemote teNotificationsSusDeviceToken deviceToken:NSData)
您的问题是,在混合Swift中不能以这种方式使用扩展名
在Swift中,您可以使用扩展为类采用的协议中声明的函数提供实现。这是“面向协议编程”的核心
在Objective-C中,类别用于向现有类添加其他函数。创建Swift扩展时,Xcode将创建targetname Swift。导出数据文件夹中的h文件。现在,您看不到此文件,因为您的编译失败了,但是如果您稍微更改扩展名以使编译正常工作
extension AppDelegate {
public func application(app application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}
}
然后查看此文件,您会发现如下内容:
@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
- (void)applicationWithApp:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
请注意扩展方法是如何作为类别html" target="_blank">添加到AppDelegate的。现在,想象一下如果您有正确的函数形式(签名中没有应用程序),该文件会是什么样子
@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
- (void)application:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
这是对已在UIApplicationDelegate协议中声明的方法的重新声明。
所有这些的结果是,您要么需要在逐个类的基础上采用Swift,要么如果您想使用逐个函数的基础上,您需要使用子类化,因为Objective-C类别和Swift扩展之间存在差异。
问题内容: 我正在尝试使用协议扩展在某些方法上添加默认行为,例如: 您可能会猜到,键盘永远不会消失。我真的看不出问题出在哪里。这是语言限制吗?有人已经成功做到了吗? 编辑: 正如@Logan所建议的,默认协议的方法实现不适用于标记为的协议。但是,具有以下签名 我已经测试了默认的实现,它似乎运行良好: 问题答案: 我不能100%积极,但是我相信这是正在发生的事情: 无法从访问协议扩展。由于是协议,因
问题内容: 当我迅速运行此代码时,我不知道为什么应用程序会在“ alertView.show()”部分显示一个断点而终止,请有人帮帮我。 问题答案: 从Xcode 6.0 UIAlertView类: 不推荐使用UIAlertView。改用UIAlertController和UIAlertControllerStyleAlert的preferredStyle。 在Swift(iOS 8和OS X 1
使用扩展可添加现有类,结构或枚举类型的功能。 使用扩展添加类型功能,但扩展无法覆盖功能。 Swift扩展功能 - 添加计算属性和计算类型属性 定义实例和类型方法。 提供新的初始化程序。 定义下标 定义和使用新的嵌套类型 使现有类型符合协议 使用关键字声明扩展名,语法如下 - 类型也可以添加扩展,使其成为协议标准,它的语法类似于类或结构。 计算属性 使用扩展,也可以扩展计算的“实例”和“类型”属性。
扩展就是向一个已有的类、结构体或枚举类型添加新功能。 扩展可以对一个类型添加新的功能,但是不能重写已有的功能。 Swift 中的扩展可以: 添加计算型属性和计算型静态属性 定义实例方法和类型方法 提供新的构造器 定义下标 定义和使用新的嵌套类型 使一个已有类型符合某个协议 语法 扩展声明使用关键字 extension: extension SomeType { // 加到SomeType
问题内容: 我正在迅速这样做: 日志给了我这个: 然后,我尝试获取间隔以进行测试: 我得到: tI = 0.0 我究竟做错了什么?我似乎可以使timeIntervalSince1970调用正常工作。在Swift中是否有与此相关的已知问题,或者我在这里缺少什么? 问题答案: 最有可能是以 毫秒为单位 的时间间隔: Swift 3及更高版本:
问题内容: 我试图在Redis中使用批处理sed替换每个密钥名称的批处理密钥重命名。(内部似乎没有更好的方法来执行此操作)。 我期望这样的输出: 相反,我只是得到这个: 这就是让我挂起来的…如何正确地获取输出并回显该输出的原始版本和编辑版本?应该工作吧?(如果是这样,我该如何正确执行?) 问题答案: 单独使用sed的解决方案 sed本身能够产生未修改的行和已修改的行: 在上面,sed首先将RENA