Could you help me to understand block types when added to containers (NSDictionary, NSArray)?

独自空忆成欢 提交于 2019-12-06 06:47:04

The type of the block object in the dictionary was already NSMallocBlock on these lines, not from copied by NSDictionary +dictionaryWithObject:forKey: method.

void (^aBlock)(NSString *someString) = ^(NSString *someString){
    NSLog(@"Block was executed. %@ %@", someString, string);
};

This aBlock variable is __strong by the default under ARC compilation environment.

__strong void (^aBlock)(NSString *someString) = ^(NSString *someString){
...

So the block object was retained by the aBlock variable. Actually, according to LLVM source code, the compiler emitted retain code for storing the object into __strong variable on the line.

  1. https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGObjC.cpp#L2091
  2. https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGObjC.cpp#L2109
  3. https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGObjC.cpp#L1920
  4. https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGObjC.cpp#L1944

EmitARCRetainBlock:

llvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value, bool mandatory) {
    llvm::Value *result = emitARCValueOperation(*this, value,
        CGM.getARCEntrypoints().objc_retainBlock, "objc_retainBlock");

This objc_retainBlock is a runtime function in objc4.

http://opensource.apple.com/source/objc4/objc4-551.1/runtime/NSObject.mm

id objc_retainBlock(id x) {
    return (id)_Block_copy(x);
}

Thus, the block object was copied from stack to heap by this _Block_copy.

In addition to this, you can see __NSStackBlock__ type for the block object using __weak.

__weak void (^aBlock)(NSString *someString) = ^(NSString *someString){
    NSLog(@"Block was executed. %@ %@", someString, string);
};

In this case, the block object was not retained by the aBlock variable, and the block object is not an ordinary Objective-C object, so the block object can exist on stack. Yes, it is __NSStackBlock__ object. You may need to call copy or Block_copy for it ahead of storing into NSMutableDictionary.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!