-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
Previous ID | SR-10498 |
Radar | rdar://problem/49987299 |
Original Reporter | marcetcheverry (JIRA User) |
Type | Bug |
Status | Resolved |
Resolution | Duplicate |
Environment
Xcode Version 10.2.1 (10E1001)
macOS 10.14.4
Additional Detail from JIRA
Votes | 1 |
Component/s | Compiler |
Labels | Bug |
Assignee | None |
Priority | Medium |
md5: c866fe67ee173d629a2501ffc7f4ee23
duplicates:
Issue Description:
Description
If you have an abstract Swift class that conforms to an Objective-C protocol, in the test case here UITableViewDataSource, which has both @required and @optional methods, implementing any optional method of that protocol in a Swift subclass will fail silently on 'Release' runtime without any compile-time warning.
Actual results
If you implement something as the below test case, which is probably very common, the Objective-C implementation of UITableView in this case (or any Objective-C implementation) will fail to detect that you actually implement that Objc-C optional protocol. You will not get your section headers in this case. This only happens under certain compilation conditions.
Expected results
The compiler should warn you at compile time that a superclass conforms to a protocol that has the same method signature marked as an Objective-C optional and you need to declare it as `@objc` for it to be exposed at runtime.
Reproduction Steps:
I could only reproduce this bug with the standard Release configuration in Xcode for Swift projects. Optimization level or other Swift compiler settings are definitely at play with this interaction with UIKit and perhaps all similar Objective-C runtime optional checking implementations. It took me significant time to catch this bug because of this and because there is absolutely no compiler warning about this.
Please note the item below is not a full test case for UITableView, but it compiles and shows that Swift does not warn about implementing these method signatures that will do nothing at runtime.
A RDAR link is attached, for whatever it's worth.
Compilation Mode must be Whole Module Optimization.
Search metadata:
`UITableView titleForHeader not getting called`, `UITableViewDelegate Swift not getting called`, `UITableViewDataSource Swift not getting called`
import UIKit
// This class is an abstract class for all table view controllers. It only implements @required methods
class BaseTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: UITableView!
// MARK: - UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
}
// This is a concrete class that now wants to implement some of the optional methods in UITableViewDelegate & UITableViewDataSource
class MyContentTableViewController: BaseTableViewController {
// This is an optional method in UITableViewDataSource
// FIXME: Compiler should warn that you need to add @objc since this matches an optional method in a protocol conformed to in the superclass, or this method won't appear as implemented to UITableView, which probably uses respondsToSelector
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section Header"
}
}