Domanda

I am trying to call a method on super class inside a block. In order to avoid a retain-cycle I need a weak reference to super. How would I get a weak reference to super?

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

I tried the following but gives a compile error.

__weak MySuperClass *superReference = super;
È stato utile?

Soluzione

You could define a helper method

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

and then do

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

A direct solution using the runtime methods looks like this:

__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));
    }
});

Disadvantages (in my opinion):

  • More (complicated) code.
  • According to the "Objective-C Runtime Programming Guide", you should never call the messaging functions directly in your code.
  • Depending on the return type of the method, you would have to use objc_msgSendSuper or objc_msgSendSuper_stret.
  • For methods taking arguments, you have to cast objc_msgSendSuper to the proper function type (thanks to @newacct).

Altri suggerimenti

Your problem can be solved by using an Objective-C runtime function objc_msgSendSuper to send a "supermessage" to weak self.

It's not possible to "get a weak reference to super", as super is a language construct rather than a separate object. Take a look at this explanation of super:What exactly is super in Objective-C?.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top