Cannot subclass a class with objc_subclassing_restricted attribute


(Rick M) #1

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
    ...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

    ...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?

···

--
Rick Mann
rmann@latencyzero.com


(Rick M) #2

Your class probably needs to be declared as open.

@objc open class Camera : NSObject {}

Thanks. Sadly, that does not fix it.

···

On Apr 14, 2017, at 22:33 , Guillaume Lessard <glessard@tffenterprises.com> wrote:

Guillaume Lessard

On Apr 14, 2017, at 20:41, Rick Mann via swift-users <swift-users@swift.org> wrote:

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
  ...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

  ...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?

--
Rick Mann
rmann@latencyzero.com

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

--
Rick Mann
rmann@latencyzero.com


(Joe Groff) #3

Subclassing Swift classes from Objective-C is not supported. If the documentation no longer mentions that restriction, we should fix that. Where is that document that you're referring to?

-Joe

···

On Apr 14, 2017, at 7:41 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
   ...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

   ...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?


(Rod Brown) #4

Hi Rick,

Unfortunately, that is the case. You cannot subclass a Swift class (even if it is a subclass of NSObject and available to the Objective-C runtime) because of deliberate limitations baked into Obj-C to block subclassing Swift classes in Obj-C code.

I believe the reason for this limitation is that Swift includes features that cannot be utilised in Obj-C and therefore subclasses would be restricted and would get undefined behaviour when implementing methods that cannot cross into Obj-C.

If Apple were to allow Obj-C -> Swift -> Obj-C subclassing, then it would be on a limited basis. Some methods wouldn’t do the same thing in Swift as they would in Obj-C selectors, and you could theoretically declare conflicting methods in your subclass that would have different actions depending on whether you were addressing the class in Swift and Obj-C. Additionally, the Swift Compiler couldn’t see beyond the Swift barrier and therefore may make optimisations that would break your Obj-C subclasses.

While I understand the frustration behind this, both in personal projects and philosophically, I think that this is unfortunately the better of the two options.

- Rod

···

On 15 Apr 2017, at 12:41 pm, Rick Mann via swift-users <swift-users@swift.org> wrote:

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
   ...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

   ...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?

--
Rick Mann
rmann@latencyzero.com

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


(Rick M) #5

This is one document that doesn't clearly state it:

  https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID136

It has nice sections like "Using Swift from Objective-C," and "Declaring a Swift Protocol That Can Be Adopted by an Objective-C Class," and "Adopting a Swift Protocol in an Objective-C Implementation," but no "Inheriting a Swift Class in Objective-C" (the discussion in such a section should explain that it can't be done and why). Searching the document for "derive", "inherit", "subclass" doesn't turn up any indication this can't be done.

Given that you can do all the other things, and there's such a thing as marking a Swift class as @objc, and you can subclass in Swift, it's quite unintuitive that you cannot go the other way.

···

On Apr 17, 2017, at 08:54 , Joe Groff <jgroff@apple.com> wrote:

On Apr 14, 2017, at 7:41 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
  ...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

  ...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?

Subclassing Swift classes from Objective-C is not supported. If the documentation no longer mentions that restriction, we should fix that. Where is that document that you're referring to?

--
Rick Mann
rmann@latencyzero.com


(Rod Brown) #6

Hi Rick,

Unfortunately, that is the case. You cannot subclass a Swift class (even if it is a subclass of NSObject and available to the Objective-C runtime) because of deliberate limitations baked into Obj-C to block subclassing Swift classes in Obj-C code.

Sorry, correction here: You cannot subclass a Swift class *in Objective C*.

···

On 18 Apr 2017, at 12:01 am, Rod Brown via swift-users <swift-users@swift.org> wrote:

I believe the reason for this limitation is that Swift includes features that cannot be utilised in Obj-C and therefore subclasses would be restricted and would get undefined behaviour when implementing methods that cannot cross into Obj-C.

If Apple were to allow Obj-C -> Swift -> Obj-C subclassing, then it would be on a limited basis. Some methods wouldn’t do the same thing in Swift as they would in Obj-C selectors, and you could theoretically declare conflicting methods in your subclass that would have different actions depending on whether you were addressing the class in Swift and Obj-C. Additionally, the Swift Compiler couldn’t see beyond the Swift barrier and therefore may make optimisations that would break your Obj-C subclasses.

While I understand the frustration behind this, both in personal projects and philosophically, I think that this is unfortunately the better of the two options.

- Rod


(Joe Groff) #7

Thanks. I'll file a bug with our documentation team to try to clarify that.

-Joe

···

On Apr 17, 2017, at 10:11 PM, Rick Mann <rmann@latencyzero.com> wrote:

On Apr 17, 2017, at 08:54 , Joe Groff <jgroff@apple.com> wrote:

On Apr 14, 2017, at 7:41 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

I'm refactoring some Objective-C code to inherit from a new Swift super class. This has been going okay, and I've been cleaning up build errors as I spot them (some auxiliary enums caused enum name changes, etc.).

But my last error seems to be that I can't subclass the Swift class: "Cannot subclass a class with objc_subclassing_restricted attribute". I didn't notice it before, and all the online references that say you can't subclass a Swift class point to a Swift document that no longer mentions that. They also don't say what they mean by "Swift" class (e.g. is it not marked with @objc?).

In any case, my Swift class looks like:

@objc
class
Camera : NSObject
{
...
}

And my ObjC class looks like:

@interface
MCPCamera : Camera

...

@end

I feel like this is a reasonable thing to try to do. Is it just not possible?

Subclassing Swift classes from Objective-C is not supported. If the documentation no longer mentions that restriction, we should fix that. Where is that document that you're referring to?

This is one document that doesn't clearly state it:

  https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID136

It has nice sections like "Using Swift from Objective-C," and "Declaring a Swift Protocol That Can Be Adopted by an Objective-C Class," and "Adopting a Swift Protocol in an Objective-C Implementation," but no "Inheriting a Swift Class in Objective-C" (the discussion in such a section should explain that it can't be done and why). Searching the document for "derive", "inherit", "subclass" doesn't turn up any indication this can't be done.

Given that you can do all the other things, and there's such a thing as marking a Swift class as @objc, and you can subclass in Swift, it's quite unintuitive that you cannot go the other way.