1

Should I copy the block passed to [c2 fun2:] based on the following class structure please?

@implementation Class1 {
    Class2 *c2;
    id var1;
}
- (void) fun1 {
    [c2 fun2:^{
        [var1 someFun];
    }];
}

@end


@implementation Class2

- (void) fun2:(void(^)(void))block {
    [self someFun1];
    block();
}

@end
Rivera
  • 10,792
  • 3
  • 58
  • 102
aprofromindia
  • 1,111
  • 1
  • 13
  • 27
  • it doesn't meter it will not compile, intention is clear. – Marek R Aug 14 '15 at 18:01
  • I'd recommend this nice quiz about blocks memory management, it has some brief and clear explanations http://blog.parse.com/learn/engineering/objective-c-blocks-quiz/ – kas-kad Aug 14 '15 at 18:45

3 Answers3

2

If you store a block to run it later (usually in some property) then you have to copy it because blocks in Objective C are created in stack. With properties it is a common approach to declare it with copy:

@property(copy) block_declaration block_name;

If you do not store a block for a later use and call it immediately (like in your case) - you do not have to copy it.

Avt
  • 16,927
  • 4
  • 52
  • 72
1

First of all you do not need to copy blocks manually under ARC (they are moved from stack to heap automatically if needed).

In your case you do not need to copy it since your block is called before fun1 ends snd it stack drains.

user996142
  • 2,753
  • 3
  • 29
  • 48
  • you have instruct ARC to create copy of block, in other case it will be retained and for blocks it is BIG mistake. – Marek R Aug 14 '15 at 18:14
  • No you do not, unless your block is __weak: http://stackoverflow.com/questions/23334863/should-i-still-copy-block-copy-the-blocks-under-arc – user996142 Aug 14 '15 at 18:16
  • Yes. Because clang knows you do not need it on heap. But when you pass it as argument to some function, and this function stores it somewhere block gets copied automatically. – user996142 Aug 14 '15 at 18:19
  • 2
    "they are moved from stack to heap automatically if needed" A block will only be moved from the stack to the heap when copied for the first time. Although the ARC specification guarantees a copy in some situations, it does not guarantee a copy in the case where you pass a block to a function with a parameter of non-block object type (like `id`), which then stores it for later use. – newacct Aug 14 '15 at 20:25
0

No you don't have to make a copy in this case. Why?

Since you do not store this block for later usage! You are just using this block immediately in invoked function, so you have a warranty that all references variables used int this block will be still valid.

You have to make a copy, if you are storing block for later usage!

I would say that it is even better to not create copy of block if it is possible. Blocks are created on stack not on heap, so creation of block is very fast operation. When you are creating a copy of block copy is created on heap (this is more expensive) and all strong references used in block have to be retained (another potentially costly operation) and some variables have to be copied (this is usually fast, except for some complex objects).

Marek R
  • 32,568
  • 6
  • 55
  • 140