Протокол Swift, вызываемый в Objective- C, не работает, и приложение вылетает с сообщением об ошибке «нераспознанный селектор» - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь заставить протокол Swift работать в файле Objective- C, но приложение вылетает при ошибке, как показано ниже.

+[OpenCamera onCameraClose]: unrecognized selector sent to class 0x102ff8580

Я не уверен, что мне не хватает .

// Swift: код UIViewController

@objc protocol CameraViewControllerDelegate {
    func onCameraClose()
}

@objc class CameraViewController: UIViewController {
   var delegate : CameraViewControllerDelegate? = nil
   func closeCamera(sender: Any) {
     delegate?.onCameraClose()
   }
}

// Objective- C: код UIViewController

OpenCamera.h

@interface OpenCamera : UIViewController <CameraViewControllerDelegate>

OpenCamera.m

#import <MyProjectName/MyProjectName-Swift.h>
@implementation OpenCamera

- (void)viewDidLoad {
    [super viewDidLoad];
    CameraViewController *cameraViewController = [[CameraViewController alloc] initWithNibName:@"CameraView" bundle:nil];
    cameraViewController.delegate = self; //Warning - Incompatible pointer types assigning to 'id<CameraViewControllerDelegate> _Nullable' from 'Class'
}
- (void)onCameraClose {
    NSLog(@"Swift Protocol method executed from Objective-C");
}
@end

1 Ответ

0 голосов
/ 28 февраля 2020

Предупреждение, приведенное здесь, на самом деле предсказывало, что cra sh:

cameraViewController.delegate = self; 
//Warning - Incompatible pointer types assigning to 'id<CameraViewControllerDelegate> _Nullable' from 'Class'

Очевидно, что self - это класс, а не экземпляр. Это очень странно.

Я предполагаю, что с вашими import договоренностями что-то не так, но вы не показали достаточно информации, чтобы понять, что это такое. Я просто покажу расположение, которое работает.

Предположим, у вас есть и Objective- C, и Swift-код в одной цели (то есть, что никакие фреймворки не задействованы). Затем в Swift вы говорите:

@objc protocol CameraViewControllerDelegate {
    func onCameraClose()
}

class CameraViewController: UIViewController {
   @objc var delegate : CameraViewControllerDelegate? = nil
   func closeCamera(sender: Any) {
     delegate?.onCameraClose()
   }
}

Обратите внимание на использование @objc var для раскрытия свойства delegate. Нет необходимости подвергать класс Objective- C, так как он уже является производной NSObject.

Хорошо, в Objective- C, вот ваш файл интерфейса:

#import <UIKit/UIKit.h>

@interface OpenCamera : UIViewController

@end

Обратите внимание, что вы не импортируете сгенерированный заголовок в .h , и вы не пытаетесь упомянуть импортированный протокол здесь.

В файле реализации:

#import "OpenCamera.h"
#import "MyProject-Swift.h"

@interface OpenCamera () <CameraViewControllerDelegate>
@end

@implementation OpenCamera

- (void)viewDidLoad {
    [super viewDidLoad];
    CameraViewController *cameraViewController = [[CameraViewController alloc] initWithNibName:@"CameraView" bundle:nil];
    cameraViewController.delegate = self;
}
- (void)onCameraClose {
    NSLog(@"Swift Protocol method executed from Objective-C");
}
@end

Мы импортируем соответствующий .h файл и сгенерированный заголовочный файл .h здесь. Мы используем анонимную категорию, чтобы объявить о соответствии протоколу, а остальное - как у вас. Вы не увидите никаких предупреждений.

...