本文的目的是介绍在子类中未调用Swift3ObjC可选协议方法的详细情况,特别关注在子类的构造方法中,必须显示调用父类的构造方法的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个
本文的目的是介绍在子类中未调用Swift 3 ObjC可选协议方法的详细情况,特别关注在子类的构造方法中,必须显示调用父类的构造方法的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解在子类中未调用Swift 3 ObjC可选协议方法的机会,同时也不会遗漏关于ios – Swift 3 ObjC可选协议方法未在子类中调用、ios – 使用Swift中的Comparable扩展@objc协议、ios – 在Swift的NSObject子类的初始化程序中调用super.init()、ios – 在子类内部实现协议方法的知识。
本文目录一览:- 在子类中未调用Swift 3 ObjC可选协议方法(在子类的构造方法中,必须显示调用父类的构造方法)
- ios – Swift 3 ObjC可选协议方法未在子类中调用
- ios – 使用Swift中的Comparable扩展@objc协议
- ios – 在Swift的NSObject子类的初始化程序中调用super.init()
- ios – 在子类内部实现协议方法
在子类中未调用Swift 3 ObjC可选协议方法(在子类的构造方法中,必须显示调用父类的构造方法)
我有以下类层次结构:
class ScrollableViewController: UIViewController, UITableViewDelegate { // ... }
实现一种UITableViewDelegate
协议方法,例如tableView:willDisplayCellAt:
在SpecificScrollableViewController
继承自的类中,ScrollableViewController
不再调用新的可选协议方法,例如tableView(_:heightForRowAt:)
答案1
小编典典tl; dr,您需要在函数声明之前添加其Objective-C声明,例如
@objc(tableView:heightForRowAtIndexPath:)func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { // return stuff}
借助《Swift 3迁移指南》,我被告知这是一个解决方案,其中指出:
如果在声明符合性的类的子类中实现可选的Objective-C协议要求,则会看到警告,“实例方法’…’几乎与协议’…’的可选要求’…’相匹配”
•解决方法:
@objc(objectiveC:name:)
在实现可选要求之前,使用原始的Objective-C选择器添加一个属性。
我相当确定这是一个错误:当协议方法位于子类中时,允许检查选择器功能的运行时动态似乎未在Grand Swift重命名中正确桥接。使用Objective-
C名称前缀函数声明可以正确地将Swift桥接到Objective-C,并允许canPerformAction:withSender:
从Objective-
C内部查询Swift 3重命名的方法
ios – Swift 3 ObjC可选协议方法未在子类中调用
class ScrollableViewController: UIViewController,UITableViewDelegate { // ... }
这实现了一个UITableViewDelegate协议方法,例如的tableView:willdisplayCellAt:
在我的类SpecificScrollableViewController中,它继承自ScrollableViewController,新的可选协议方法不再被调用.的tableView(_:heightForRowAt
总结
以上是小编为你收集整理的ios – Swift 3 ObjC可选协议方法未在子类中调用全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
ios – 使用Swift中的Comparable扩展@objc协议
以下简短示例仅使用Equatable来显示错误.
@objc protocol Option: Equatable { var title: String { get } var enabled: Bool { get } var position: Int { get } } func ==(lhs: Option,rhs: Option) -> Bool { return lhs.position == rhs.position }
Option协议必须标记为@objc或从NSObjectProtocol继承,因为它将与UIKit一起使用.
错误:
>
@objc protocol ‘Option’ cannot refine non-@objc protocol
‘Equatable’
>
Protocol ‘Option’ can only be used as a generic constraint
because it has Self or associated type requirements
你有什么建议如何解决这个问题?
解决方法
具有Self要求的协议(即,协议声明中的至少一个方法包含Self)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如,func doSomething< T:Option>(参数:T).
从Option协议声明中删除Equatable,并在Option上声明== as generic将解决编译错误.至于排序,你也可以重载<运算符,并通过该运算符排序(无需实现Comparable):
@objc protocol Option { var title: String { get } var enabled: Bool { get } var position: Int { get } } func ==<T: Option>(lhs: T,rhs: T) -> Bool { return lhs.position == rhs.position } func <<T: Option>(lhs: T,rhs: T) -> Bool { return lhs.position < rhs.position }
这允许您将符合协议的对象传递给UIKit,并在快速代码中对它们进行比较.
class A: NSObject,Option { .. } class B: NSObject,Option { ... } let a = A() let b = B() a == b // compiles,and returns true if a and b have the same position let c: [Option] = [a,b] c.sort(<) // returns a sorted array by the `position` field
关于上面的排序代码的一个重要注意事项:如果你没有为c指定类型,那么编译器会将其类型推断为[NSObject],并且由于<的不明确性,排序调用将无法编译.操作符.您需要将c显式声明为[Option]以利用重载运算符.
ios – 在Swift的NSObject子类的初始化程序中调用super.init()
Lister使用两个模型对象:List和ListItem.我发现他们都不会在初始化器中调用super.init(),即使它们是NSObject子类.
然而,在Lister的Objective-C版本中,两个模型对象(AAPLList和AAPLListItem)都调用[super init].
Swift编程语言清楚地表示:“指定的初始化程序必须从其直接超类调用指定的初始化程序”(初始化程序初始化器链接的规则1)
这里发生了什么?为什么这是一个异常,如果你不应该总是在一个子类中调用super.init(),那么什么规则适用?
解决方法
NSObject只有默认的初始化(init());您可以通过在不调用super.init()的构造函数中尝试引用self(例如.println(self)),在子类初始化器的末尾调用超类初始化器:您不允许这样做,因为那个阶段还没有完全初始化.
如果要在构造函数中使用自己的某个地方,则需要在该点完全构造对象,因此您需要在此之前手动调用super.init().
ios – 在子类内部实现协议方法
open class FormViewController : UIViewController { } extension FormViewController : UITableViewDelegate { func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { // some default implementation } /// some other UITableViewDelegate methods follow,but _NOT_ willdisplayCell }
我试图继承FormViewController并为tableView添加一个实现(_:willdisplay:forRowAt :)(这是UITableViewDelegate的可选方法).此方法在原始FormViewController中没有实现:
import UIKit import Eureka class MyViewController: FormViewController { override func viewDidLoad() { let tableView = UITableView(frame: self.view.bounds,style: .grouped) tableView.delegate = self tableView.dataSource = self self.tableView = tableView self.view.addSubview(self.tableView!) super.viewDidLoad() form = Form() let section = Section() section.append(EmailRow(){ $0.tag = "email" $0.title = "Email" }) form += [section] } func tableView(_ tableView: UITableView,willdisplay cell: UITableViewCell,forRowAt indexPath: IndexPath) { print("NOT CALLED") } override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) { print("will be called") } override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { print("GETS CALLED") return super.tableView(tableView,cellForRowAt: indexPath) } } /// somewhere else: self.navigationController?.pushViewController(MyViewController(),animated: true)
使用此设置,将调用tableView(_:cellForRowAt :)的覆盖版本(意味着正确设置了tableView.delegate).不会调用tableView(_:willdisplay:forRowAt :).只要我在Eureka中添加一个空白实现,我就可以覆盖该方法.
问题:为什么Swift在超类中没有默认实现时不使用该方法?
解决方法
首先,您可以在扩展中实现委托方法,并在子类中覆盖它.这将确保调用该方法.
extension FormViewController : UITableViewDelegate { func tableView(_ tableView: UITableView,forRowAt indexPath: IndexPath) { // you can leave the implementation blank if you want } } class MyViewController: FormViewController { override func tableView(_ tableView: UITableView,forRowAt indexPath: IndexPath) { print("CALLED!!") } }
其次,您可以使用pre-Swift 3表示法声明该方法,它将起作用.这部分对我来说也是一个错误(或同一个bug的所有部分).我不推荐这个选项,因为它可能会在未来的Swift或Xcode版本中发生变化,并且通常会感觉很乱.
extension FormViewController : UITableViewDelegate { // no willdisplayCell method } class MyViewController: FormViewController { func tableView(_ tableView: UITableView,willdisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) { print("CALLED!!") } }
编辑:OP将UITableViewDelegate方法放在扩展中的事实不会导致问题.即使类本身对委托进行了decalres,问题仍然存在.
关于在子类中未调用Swift 3 ObjC可选协议方法和在子类的构造方法中,必须显示调用父类的构造方法的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于ios – Swift 3 ObjC可选协议方法未在子类中调用、ios – 使用Swift中的Comparable扩展@objc协议、ios – 在Swift的NSObject子类的初始化程序中调用super.init()、ios – 在子类内部实现协议方法的相关信息,请在本站寻找。
本文标签: