2

To avoid capturing of 'self' in a block, we often use a weak pointer. However, for some 'non-property' ivars (otherValue in this example):

@implementation MyClass
{
    NSString *otherValue;
}

We need a strong ref and an arrow accessor (->) usually done like:

MyClass *blockself = weakself;
blockself->otherValue

The problem is, accessing blockself->otherValue will crash if blockself is nil.

I can check for if (blockself), but it 'can' be release right after, in the next line.

Example:

__weak MyClass *weakself = self;

[serverManager runSomething:^(Result *res) {

    // If pointer (weakself) is released, no problem. Accessing though a 'property'
    if (weakself.value) {

    }

    // For local iVars though:

    MyClass *blockself = weakself;

    // This will crash if 'blockself' is nil
    if (blockself->otherValue) {

    }

    // Can test for nil here

    if (blockself) {

        // But..
        // Potentiall, the pointer 'could' be released here

        if (blockself->_value) {

        }

    }

So, is the only safer way is to migrate from iVars to use a @property? Is there a 'safe' way to access iVars thought an arrow (->) accessor?

bauerMusic
  • 5,470
  • 5
  • 38
  • 53
  • 2
    The point of capturing strongly in the block is to prevent the release of said object. In our code, we avoid using `->` entirely. Just use the property directly. The reference to blockSelf will keep the object alive. – bbum Jun 09 '19 at 15:40
  • @bbum Your post here: https://stackoverflow.com/questions/39938439/does-assigning-a-weak-pointer-to-a-strong-pointer-copy-the-object Pretty much clears it. – bauerMusic Jun 09 '19 at 18:57
  • I'm confused a little, why crash at `->`? what's the detailed crash? – Itachi Jun 11 '19 at 08:36
  • @Itachi `nil->value` will crash. – bauerMusic Jun 11 '19 at 19:10
  • If the `weakself` is nil before assigning to `blockself`, ```if (blockself && blockself->otherValue)``` should be safe. If the `weakself` is not nil before that, then `blockself` make the original object's retained count increased by 1, `blockself` won't be released until the containing block get executed. – Itachi Jun 12 '19 at 02:44
  • @Itachi It makes sense to assign `blockself` only if 'weakself' in not nil. Although, I think that the block context is not 'expected' to continue executing in such context (a view that was released for example). But yes, if `blockself` is assigned a non nil, it will hold it for the block scope. – bauerMusic Jun 12 '19 at 10:12

0 Answers0