Fast generics and protocols not working on UIKit [possible error]

TL DR → scroll down

When trying to bind Apple to protocol-oriented programming using Swift, I came across the following problem, trying to implement a delegation pattern between classes.

I will start with this example:

protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: PhotoHandlerParent } 

So far so good. The MyViewController instance will be happily assigned as the PhotoHandler delegate. But I will say that I not only wanted the delegate object to match PhotoHandlerParent , but also had a UIViewController class. In this particular example, so that PhotoHandler can submit and reject the UIImagePickerController on behalf of its parent view controller. Is very similar:

 protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: UIViewController, PhotoHandlerParent } 

Unfortunately, the above code does not work on Swift. On the other hand, although Swift has Generics, this may help in this case. So you can try:

 protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler<Parent where Parent: UIViewController, Parent: PhotoHandlerParent>: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: Parent } 

Now, interestingly, the MyViewController instance will return to a happy appointment as a PhotoHandler delegate. Compilation error, no runtime error. But...

TL DR: problem

By running the sample code for this question, you can see that an instance of a class declared using Generics and set as a UIImagePickerController delegate is never called by this. An instance of a declared object without is generated using the UIImagePickerController .

My best guess is that the compiler is not complaining because it can make sure that PhotoHandler matches UIImagePickerControllerDelegate . However, at run time, the instance of PhotoHandler is actually an instance of PhotoHandler<MyViewController> , so it somehow prevents the UIImagePickerController identifying that its delegate is actually implementing its protocol.

Or am I missing something?

Greetings

+2
source share
1 answer

This is the correct behavior from a documentation point of view because:

A method in a generic class cannot be represented in Objective-C


Reply to comment on @Bell App Lab:

Open this page and scroll down to Easy General. Here's a note:

In addition to these Foundation collection classes, Objective-CSwift ignores lightweight generics. Any other types that use light generics are imported into Swift, as if they were unparameterized.

It is mainly said that generics (ObjC → Swift) are imported only for Foundation collection classes, and rest is ignored - IOW is imported as if they were not parameterized.

Perhaps we can expect some improvement in this area in the future, but I doubt it.

+2
source

Source: https://habr.com/ru/post/1238706/


All Articles