Two Obj-C visible functions no longer overload?


(Jon Shier) #1

Swifters:
  I’m attempting to update some library code to beta 4 and I’ve run into something that’s either a bug or a deliberate change. In a class that’s a Foundation.Operation subclass, there are two finish() functions:

final func finish(_ receivedErrors: [Error] = []) {
    _finish(receivedErrors, fromCancel: false)
}

/// Convenience method to simplify finishing when there is only one error.
final func finish(_ receivedError: Error?) {
    finish(receivedError.map { [$0]} ?? [])
}

Prior to beta 4 these functions lived side by side quite happily. In beta 4, however, their existence produces this error:

method 'finish' with Objective-C selector 'finish:' conflicts with previous declaration with the same Objective-C selector

Now, if I mark one of the functions @nonobjc, it compiles. So is this a bug or change in behavior?

Jon Shier


(Quinn “The Eskimo!”) #2

NSOperation has a property with `-finished:` as the setter and `-isFinished` as the getter. It’s not uncommon for method names used by an operation’s author to collide with these, depending on exactly how the importing is importing those methods, how the overlays are set up, and so on.

IMO the best way to fix your specific issue is to adopt Swift 3 naming for your methods:

    final func finish(receivedErrors: [Error])
    final func finish(receivedError: Error?)

which lifts you out of the ‘finish’ space entirely.

Share and Enjoy

···

On 5 Aug 2016, at 22:57, Jon Shier via swift-users <swift-users@swift.org> wrote:

Now, if I mark one of the functions @nonobjc, it compiles. So is this a bug or change in behavior?

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware


(Jordan Rose) #3

I would definitely expect these two to conflict, so if they previously compiled happily I would guess that’s a bug we fixed. The most likely possibility is that we didn’t allow making arrays of errors and now we do.

Jordan

···

On Aug 5, 2016, at 14:57, Jon Shier via swift-users <swift-users@swift.org> wrote:

Swifters:
  I’m attempting to update some library code to beta 4 and I’ve run into something that’s either a bug or a deliberate change. In a class that’s a Foundation.Operation subclass, there are two finish() functions:

final func finish(_ receivedErrors: [Error] = []) {
    _finish(receivedErrors, fromCancel: false)
}

/// Convenience method to simplify finishing when there is only one error.
final func finish(_ receivedError: Error?) {
    finish(receivedError.map { [$0]} ?? [])
}

Prior to beta 4 these functions lived side by side quite happily. In beta 4, however, their existence produces this error:

method 'finish' with Objective-C selector 'finish:' conflicts with previous declaration with the same Objective-C selector

Now, if I mark one of the functions @nonobjc, it compiles. So is this a bug or change in behavior?

Jon Shier
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Jon Shier) #4

Jordan:
  Could you expand on allowing making arrays of errors? AFAIK, making arrays of ErrorProtocol/ErrorType/Error has always been possible. And somewhat coincidentally I ran into a runtime issue with the same library, fixed in the latest Swift trunk package, that would result in a crash when attempting to access an array of Errors through an intermediate derived property, but only in Objective-C derived classes. Perhaps that’s related?
  In any event, if we wished to maintain Objective-C visibility here, I would expect adding different external labels to fix the issue, right?

Jon

···

On Aug 8, 2016, at 5:04 PM, Jordan Rose <jordan_rose@apple.com> wrote:

I would definitely expect these two to conflict, so if they previously compiled happily I would guess that’s a bug we fixed. The most likely possibility is that we didn’t allow making arrays of errors and now we do.

Jordan

On Aug 5, 2016, at 14:57, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Swifters:
  I’m attempting to update some library code to beta 4 and I’ve run into something that’s either a bug or a deliberate change. In a class that’s a Foundation.Operation subclass, there are two finish() functions:

final func finish(_ receivedErrors: [Error] = []) {
    _finish(receivedErrors, fromCancel: false)
}

/// Convenience method to simplify finishing when there is only one error.
final func finish(_ receivedError: Error?) {
    finish(receivedError.map { [$0]} ?? [])
}

Prior to beta 4 these functions lived side by side quite happily. In beta 4, however, their existence produces this error:

method 'finish' with Objective-C selector 'finish:' conflicts with previous declaration with the same Objective-C selector

Now, if I mark one of the functions @nonobjc, it compiles. So is this a bug or change in behavior?

Jon Shier
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Jordan Rose) #5

It’s always been possing to make arrays of Error, but exposing those arrays back to Objective-C may or may not have worked correctly (as you noticed).

And yes, your solutions are either adding different labels, or using the ‘objc’ attribute to explicitly specify a selector for one or the other.

Jordan

···

On Aug 8, 2016, at 16:35, Jon Shier <jon@jonshier.com> wrote:

Jordan:
  Could you expand on allowing making arrays of errors? AFAIK, making arrays of ErrorProtocol/ErrorType/Error has always been possible. And somewhat coincidentally I ran into a runtime issue with the same library, fixed in the latest Swift trunk package, that would result in a crash when attempting to access an array of Errors through an intermediate derived property, but only in Objective-C derived classes. Perhaps that’s related?
  In any event, if we wished to maintain Objective-C visibility here, I would expect adding different external labels to fix the issue, right?

Jon

On Aug 8, 2016, at 5:04 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

I would definitely expect these two to conflict, so if they previously compiled happily I would guess that’s a bug we fixed. The most likely possibility is that we didn’t allow making arrays of errors and now we do.

Jordan

On Aug 5, 2016, at 14:57, Jon Shier via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Swifters:
  I’m attempting to update some library code to beta 4 and I’ve run into something that’s either a bug or a deliberate change. In a class that’s a Foundation.Operation subclass, there are two finish() functions:

final func finish(_ receivedErrors: [Error] = []) {
    _finish(receivedErrors, fromCancel: false)
}

/// Convenience method to simplify finishing when there is only one error.
final func finish(_ receivedError: Error?) {
    finish(receivedError.map { [$0]} ?? [])
}

Prior to beta 4 these functions lived side by side quite happily. In beta 4, however, their existence produces this error:

method 'finish' with Objective-C selector 'finish:' conflicts with previous declaration with the same Objective-C selector

Now, if I mark one of the functions @nonobjc, it compiles. So is this a bug or change in behavior?

Jon Shier
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users