New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-10257] Inference of @objc from witnessed protocol requirement fails sometimes #52657
Comments
A code example, because a wall of descriptive text is hard to read: // BaseVC.swift
import UIKit
class BaseVC: UIViewController, UITableViewDelegate {} // ChildVC.swift
import UIKit
class ChildVC: BaseVC {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
} // UnrelatedView.swift
import UIKit
class UnrelatedView: UIView {
var selectionFeedbackGenerator: AnyObject?
func breakThings() {
// Comment out this line to make the bug go away
selectionFeedbackGenerator?.selectionChanged()
}
} Given just that code and the conditions detailed above*, ChildVC will not be notified when a table row is selected, because it does not implement the ObjC method * (Swift 5.0 compiler, |
Thank you for putting the effort in to track this down! |
Someone else ran into this here: https://stackoverflow.com/questions/55592341/xcode-10-2-protocol-inheritance-issue/55593277 |
Comment by Dimitar Topalov (JIRA) I believe this needs a higher priority, as it can raise some serious issues that are hard to catch until the app is archived. |
Comment by Robin Trigodet (JIRA) I had it too. The solution is to add @objc before protocol function |
Comment by Dan Hogan (JIRA) I agree that this issue needs a higher priority. I work on a large project and we are not confident that we can identify all of the affected files. For now we are delaying swift 5 migration and using XCode 10.1 due to this issue |
Comment by Lance (JIRA) I believe there is some other trigger or variation that causes this to happen as well. In our project the exact same thing happens (no @objc inference for protocol methods first implemented in a subclass), with a couple of differences:
Happens every time when whole module. I have been unable to reproduce the incremental build version in a simple project so far. |
Comment by Alicia Tams (JIRA) We're seeing the same thing on our recent update to Swift 5. Almost dead in the water because we're going from 3.2 to 5 and really cannot wait until Xcode 11 is in GM or released to release our app. We also can no longer debug to our phones because iOS enjoys upgrading to the latest version without consent after we explicitly decline to update a number of times over the course of a few weeks. Our codebase is quite large and these are silent failures, finding them all is going to be a nightmare. Will this possibly be hot fixed in the 5 compiler in an Xcode 10.2.2 update? |
Comment by Kiel (JIRA) I strongly plead for an Xcode 10.2.2 hotfix update. As with others, we're stuck with Xcode 10.1 because those silent failures we know about are causing issues. Further, due to the subtly of the bug's side effects, we don't know what other issues this introduces, especially with third party SDKs and UIKit, such as delegate methods (where we are especially bitten). Since those methods are not exposed to the Objective-C runtime, things just break or stop working altogether. Please consider hotfixing Xcode 10.2.1 for this. |
Comment by Kiel (JIRA) This seems to happen for us irrespective of whole module or incremental compilation. |
Comment by Jasper (JIRA) Status resolved with no open duplicates? I still have the problem on a generic class (generic UITableView type) on every tableview delegate methods. I have seen this bug in Xcode 10.2.?, Xcode 11 beta 1, 2 and 3 (so the current Xcode version) with Swift 5.0 and 5.1. I now just override everything (https://stackoverflow.com/a/55594515/7715250) and someone else also got my problem (https://stackoverflow.com/questions/55592341/xcode-10-2-with-swift-5-0-compiler-protocol-inheritance-issue#comment99581546_55593277). Is this bug considered closed and fixed? I can try to create a reproduction project if needed. |
Yes this bug is considered fixed in Swift 5.1. If you are seeing a similar issue in the latest beta, please file a new bug with a reproducer project. |
Comment by Claus Joergensen (JIRA) @slavapestov hey, people are suggesting the fix was backported to Xcode 10.3, can this be confirmed or denied by the Swift team? Thanks |
Comment by Christian Gossain (JIRA) This just happened to me with Xcode 10.3 and Swift 5. I found out too late because this only shows up in the release version that was released to the public. Anyways, I just disabled "Whole Module" optimization on my "Release" target and this solved the issue for now. Hopefully this issue get's fixed in the next release. |
Attachment: Download
Environment
Swift 5.0 (Xcode 10.2.0)
macOS 10.14.4
Additional Detail from JIRA
md5: a179bcfc08d34eda3229b62320cb8489
is duplicated by:
Issue Description:
The short version: In certain cases, the Swift 5.0 compiler does not infer
@objc
correctly for a function. This only happens inwholemodule
mode, which means that there's an observable behavior difference between incremental and whole-module compilation.There are three files involved:
BaseVC.swift
ChildVC.swift
UnrelatedClass.swift
BaseVC declares conformance to UITableViewDelegate, but does not implement anything.
ChildVC implements '
func tableView(_:didSelectRowAt:)
'The app delegate checks whether ChildVC responds to
-tableView:didSelectRowAtIndexPath:
. Up to this point, it does.Now we add in a third file, "UnrelatedClass.swift"
If all of the following hold true, then the ChildVC.respondsToSelector() check fails:
1. The third file contains an 'AnyObject'-dispatched call to .selectionChanged()
2. The order of the files passed to the compiler is [BaseVC, UnrelatedClass, ChildVC].
3.
ChildVC.tableView(_:didSelectRowAt:)
is not tagged@objc
4. The compiler is running in 'wholemodule' mode.
In that case, the ObjC runtime does not see the implementation of
-tableView:didSelectRowAtIndexPath:
.Only under those four conditions does this bug appear.
In Swift 4.2,
@objc
was inferred. In Swift 5.0 incremental mode,@objc
is inferred.I'm attaching a sample Xcode project which reproduces the issue easily. Just look at the console output on launch.
The text was updated successfully, but these errors were encountered: