There is a question about whether blocks are on the stack or on the heap. As you’ve seen before, block properties are now automatically copied without having to write the copy keyword. So did a few experiments, want to see under what circumstances will automatically copy, under what circumstances not ~

The experiment

The code is as follows:

TestClass.h
typedef void(^SimpleBlock)();

@interface TestClass : NSObject

@property (nonatomic, copy) SimpleBlock copyProperty;

@property (nonatomic, strong) SimpleBlock strongProperty;

@property (nonatomic, weak) SimpleBlock weakProperty;

@property (nonatomic, assign) SimpleBlock assignProperty;

@endCopy the code
main
#import "TestClass.h"

SimpleBlock someFunction(SimpleBlock block) {
    NSLog(@"block as param : %@", block);
    return block;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        __block int a = 1;

        NSLog(@"orginal block : %@", ^{
            a = 2;
        });

        // as a variable
        SimpleBlock block = ^{
            a = 2;
        };
        NSLog(@"block as variable : %@", block);
        __weak SimpleBlock weakBlock = ^{
            a = 2;
        };
        NSLog(@"block as a weak variable : %@", weakBlock);

        // as properties
        TestClass* testClass = [TestClass new];
        testClass.weakProperty = ^{
            a = 2;
        };
        testClass.assignProperty = ^{
            a = 2;
        };
        testClass.copyProperty = ^{
            a = 2;
        };
        testClass.strongProperty = ^{
            a = 2;
        };

        NSLog(@"copy property : %@", testClass.copyProperty);
        NSLog(@"strong property : %@", testClass.strongProperty);
        NSLog(@"weak property : %@", testClass.weakProperty);
        NSLog(@"assign property : %@", testClass.assignProperty);

        NSLog(@"block as return value : %@", someFunction(^{
            a = 2;
        }));
    }
    return 0;
}Copy the code

Experimental results:

2017.- 06 17:43:36.207212 test2[27378:1079138] orginal block : <__NSStackBlock__: 0x7ffF5FBff728 > 2017-02-06 17:43:36.207436 test2[27378:1079138] Block as variable: <__NSMallocBlock__: 0x100402F70 > 2017-02-06 17:43:36.207457 test2[27378:1079138] Block as a weak variable: <__NSStackBlock__: 0x7ffF5FBff6b8 > 2017-02-06 17:43:36.207492 test2[27378:1079138] Copy Property: <__NSMallocBlock__: 0x100403140> 2017-02-06 17:43:36.207517 test2[27378:1079138] Strong Property: <__NSMallocBlock__: 0x100403170> 2017-02-06 17:43:36.207563 test2[27378:1079138] Weak Property: <__NSStackBlock__: 0x7ffF5FBff668 > 2017-02-06 17:43:36.207581 test2[27378:1079138] Assign Property: <__NSStackBlock__: 0x7ffF5FBFF640 > 2017-02-06 17:43:36.207611 test2[27378:1079138] Block as param: <__NSStackBlock__: 0x7ffF5FBFF618 > 2017-02-06 17:43:36.207769 test2[27378:1079138] Block as return value: <__NSMallocBlock__: 0x100600000>Copy the code

Analysis of the

  • As a variable:
    • A block is first declared on the stack
    • Assignment to a normal variable is copied to the heap
    • Assignment to a weak variable will not be copied
  • As an attribute:
    • Properties modified with strong and copy are copied
    • Weak and assign attributes will not be copied
  • Function parameters:
    • Functions passed as arguments will not be copied
    • The return value of the function is copied

guess

Retain blocks are automatically copied, including autoRelease~, which explains why function arguments are not copied and return values are copied. Does that make a lot of sense

Thank you for your support of this experiment