Цель C - Слабая ссылка на суперкласс?

Я пытаюсь вызвать метод супер класса внутри блока. Чтобы избежать цикла сохранения, мне нужна слабая ссылка на супер. Как я могу получить слабую ссылку на супер?

[self somethingWithCompletion:^(){
   [super doStuff];
}];

Я попробовал следующее, но дал ошибку компиляции.

__weak MySuperClass *superReference = super;

Ответ 1

Вы можете определить вспомогательный метод

-(void) helperMethod
{
    [super doStuff];
    // ...
    [super doOtherStuff];
    // ...
}

а затем do

__weak MyClass *weakSelf = self;
[self somethingWithCompletion:^(){
    MyClass *strongSelf = weakSelf;
   [strongSelf helperMethod];
}];

Прямое решение, использующее методы выполнения, выглядит следующим образом:

__weak MyClass *weakSelf = self;
[self somethingWithCompletion:^(){
    MyClass *strongSelf = weakSelf;
    if (strongSelf) {
        struct objc_super super_data = { strongSelf, [MyClass superclass] };
        objc_msgSendSuper(&super_data, @selector(doStuff));
    }
});

Недостатки (на мой взгляд):

  • Более сложный код.
  • В соответствии с "Objective-C Runtime Programming Guide" вы никогда не должны звонить функции обмена сообщениями непосредственно в вашем коде.
  • В зависимости от типа возвращаемого метода вы должны использовать objc_msgSendSuper или objc_msgSendSuper_stret.
  • Для методов, принимающих аргументы, вы должны использовать objc_msgSendSuper для правильного (благодаря @newacct).

Ответ 2

Ваша проблема может быть решена с помощью функции Objective-C времени выполнения objc_msgSendSuper для отправки "супермассы" на слабую self.

Невозможно "получить слабую ссылку на супер", поскольку super - это языковая конструкция, а не отдельный объект. Взгляните на это объяснение super: что именно супер в Objective-C?.