Неоднозначная ссылка на члена «делегата»

0

Я пытаюсь создать экземпляр одноэлементного класса, написанного в Objective-C. Я должен соответствовать этому протоколу делегирования. Реализация Swift выглядит примерно так:

class SomeClass: ManagerDelegate {
  let manager = Manager.sharedInstance()

  func someFunction(){
    manager.delegate = self
  }
}

Класс Single-Object Object-C выглядит примерно так:

// header
@protocol ManagerDelegate <NSObject>
@required
-(void)delegateMethod;
@end

@interface Manager : NSObject {

}
+ (id)sharedInstance;
@property (nonatomic, assign) id delegate;
@end


// class file
+ (id) sharedManager{
  static Manager *theSharedManager = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    theSharedManager = [[self alloc] init];
  });

  return theSharedManager;
}

- (void) someInternalMethod{
  [delegate delegateMethod];
}

После указания делегата (manager.delegate = self), я получаю ошибку

Неоднозначная ссылка на делегата участника '

Является ли класс Objective-C некорректно сформированным или я его неправильно реализую? Я что-то пропустил?

  • 0
    Вы говорите: «Синглтон-класс Objective C выглядит примерно так»; Синглтон наследуется только от NSObject или же он наследуется от какого-то другого объекта?
  • 0
    Я настроил тест, который наследуется только от NSObject и все еще получает неоднозначную ошибку ссылки.
Показать ещё 1 комментарий
Теги:
delegates

2 ответа

2
Лучший ответ

Ваша проблема вызвана определением вашего метода sharedInstance в Objective-C. Объявив это как

+ (id)sharedInstance;

он преобразуется в sharedInstance() → AnyObject! в Свифт. Swift тогда не знает, какой из многих потенциальных свойств delegate он может найти, что вы имеете в виду. Если вы измените декларацию и реализацию Objective C:

+ (instancetype)sharedInstance;

ваша проблема исчезнет.

И как указывает @rmaddy, ваш делегат должен быть weak не assign. Если вы используете assign то delegate будет оставлен как недопустимый указатель в том случае, если делегат будет освобожден.

Кроме того, использование делегата с синглоном несколько противоречиво. Учитывая, что у вас будет только один экземпляр Manager который может использоваться рядом других объектов, и вы можете иметь только один активный делегат одновременно, существует вероятность конфликтов.

Я бы предположил, что либо блоки/закрытия, либо NSNotification - лучший подход к NSNotification из одноэлементного.

1

Это потому, что всякий раз, когда вы приводите экземпляр из объектного кода c в swift, он дает как AnyObject, так что

let manager = Manager.sharedInstance() //manager is AnyObject due to bridging between objc and swift

дает вам свойство AnyObject для менеджера. Вам необходимо принудительно применить этот AnyObject к Manager для использования в качестве экземпляра менеджера, как показано ниже.

class SomeClass: NSObject, ManagerDelegate {
    let manager = Manager.sharedInstance() as! Manager //here was your error

    func someFunction(){
        manager.delegate = self
    }
    func delegateMethod() {
        print("Hello")
    }
}

Надеюсь, это решает вашу проблему :)

  • 0
    Разве это не будет исправлено, если код Objective C правильно sharedInstance чтобы возвращать instancetype вместо id ?
  • 0
    да отлично это тоже решит. Я не знаю, цель-c, поэтому я дал решение, что я мог понять из Swift.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню