Skip to content
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-2817] selector mismatch with obj-c delegates + extensions #45421

Open
swift-ci opened this issue Oct 1, 2016 · 7 comments
Open

[SR-2817] selector mismatch with obj-c delegates + extensions #45421

swift-ci opened this issue Oct 1, 2016 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 1, 2016

Previous ID SR-2817
Radar rdar://28579406
Original Reporter cezarywojcik (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 5
Component/s
Labels Bug
Assignee None
Priority Medium

md5: 9c5b0f645140d6f33adb8b7c263e85dd

is duplicated by:

  • SR-2885 Optional protocol method does not follow Swift 3 method name translation rule in subclass

Issue Description:

Summary:
When protocol conformance functions are added within an extension that doesn't explicitly declare itself to conform to this protocol, you get an error that says that the obj-c selectors don't match. This is weird, but at least we get an error. Even worse is that if this happens in a subclass, it fails silently, which can cause hard-to-find errors.

Steps to Reproduce:
Case 1: There is an error:

@belkadan
Copy link
Contributor

belkadan commented Oct 3, 2016

@DougGregor, you changed this, right?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 3, 2016

Comment by Cezary Wojcik (JIRA)

Some context here: since this used to work in Swift 2.3, in the migration from 2.3 to 3.0, there are now a LOT of hard-to-find silent bugs that have been introduced as a result of the migration. It's pretty scary.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2016

Comment by Jacek (JIRA)

+1 this is very unpleasant

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2016

Comment by Alex Matjuk (JIRA)

• 2nd case is not a bug because method is optional.
• 1st case could be fixed by adding @objc(collectionView:layout:sizeForItemAtIndexPath: ) attribute (as Xcode already suggests). But I agree such conversion should be applied automatically

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2016

Comment by Alex Matjuk (JIRA)

Actually bugs are:

  1. no warning to add renaming @objc attribute when method is implemented inside class itself:
class Test: UIViewController, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 150.0, height: 150.0)
    }
}

2) no warning to add renaming @objc attribute when method is implemented inside class extension which adds protocol conformance:

extension Test: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 150.0, height: 150.0)
    }
}

3) no warning to add renaming @objc attribute in subclass both inside class itself

class Test: UIViewController, UICollectionViewDelegateFlowLayout {}

class TestSubclass: Test {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 150.0, height: 150.0)
    }
}

or its extension

class Test: UIViewController, UICollectionViewDelegateFlowLayout {}

class TestSubclass: Test {}

extension TestSubclass  {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 150.0, height: 150.0)
    }
}

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2016

Comment by Alex Matjuk (JIRA)

Is reproducible with any protocol which uses NS_SWIFT_NAME. E.g.

@protocol TestProtocol <NSObject>

- (void) objc_protocolMethod NS_SWIFT_NAME(swift_protocolMethod()) ;

@end

@swift-ci
Copy link
Collaborator Author

Comment by Daniel Resnick (JIRA)

This appears to be fixed in Swift 3.0.1 for normal subclasses, but is not fixed for generic subclasses:

class A: NSObject, UITableViewDelegate {}

class B: A {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
}

class C<T>: A {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
}

print(#selector(B.tableView(_:didSelectRowAt:))) // tableView:didSelectRowAtIndexPath:
print(#selector(C<Int>.tableView(_:didSelectRowAt:))) // tableView:didSelectRowAt:

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

2 participants