Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C - Weak reference to super class?

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;
like image 795
aryaxt Avatar asked Dec 13 '13 18:12

aryaxt


People also ask

What is a weak reference Objective C?

Pointers that are not retained are often referred to as “weak” in Objective-C documentation that predates the garbage collector. These are references that are allowed to persist beyond the lifetime of the object. Unfortunately, there is no automatic way of telling whether they are still valid.

What is strong reference and weak reference in Objective C?

A reference to an object is any object pointer or property that lets you reach the object. There are two types of object reference: Strong references, which keep an object “alive” in memory. Weak references, which have no effect on the lifetime of a referenced object.

How do you declare a weak self in Objective C?

The simplest way to create such scope is to declare another block: void(^intermediateBlock)(__typeof(self) __weak self) = ^(__typeof(self) __weak self) { // self is weak in this scope ^{ // self is weak here too [self doSomeWork]; }; };

What is super in Objective C?

Super is self , but when used in a message expression, it means "look for an implementation starting with the superclass's method table."


1 Answers

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).
like image 65
Martin R Avatar answered Sep 20 '22 19:09

Martin R