美文网首页程序员
block-对象类型的auto变量

block-对象类型的auto变量

作者: RM_乾笙 | 来源:发表于2018-07-03 11:49 被阅读30次

从上些章节block-变量的捕获(caputer)中,详细说了基本类型的auto变量的捕获,现在来了解下,对象类型的auto变量是怎样捕获和底层结构是如何的。

block自动copy的情况

在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,比如以下情况

  • block作为函数返回值时
  • block赋值给__strong指针时
  • block作为Cocoa API中方法名含有usingBlock的方法参数时
  • block作为GCD API的方法参数时

#import <Foundation/Foundation.h>
#import "RMPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...        
        RMPerson *person = [[RMPerson alloc] init];
        person.age = 20;
        
        void (^block)(void) = ^ {
            NSLog(@"age is %d",person.age);
        };

        [person release];
        NSLog(@"-----------");
    }
    return 0;
}

----------------- RMPerson.h -----------------
#import <Foundation/Foundation.h>
@interface RMPerson : NSObject
@property (nonatomic, assign) int age;
@end

----------------- RMPerson.m -----------------
#import "RMPerson.h"
@implementation RMPerson
- (void)dealloc {
    [super delloc];
    NSLog(@"RMPerson-delloc");
}
@end


// MRC 环境 控制台输出 
2018-07-03 10:34:39.523223+0800 __block的本质[20912:1898201] RMPerson-delloc
2018-07-03 10:36:17.021712+0800 __block的本质[20912:1898201] -----------
Program ended with exit code: 0

留意上面代码,是在MRC的环境下的代码,当NSLog(@"-----------");打印前了,RMPerson就释放了,什么原因呢?虽然block访问的是对象类型的auto变量,但还是访问了auto变量,所以block是属于NSStackBlock,是存在栈空间的,block运行完就会释放,它自己都不知道自己能存活多久,所以是不会作强持有RMPerson的操作。(结论一:如果block是在栈上,将不会对auto变量产生强引用)


#import <Foundation/Foundation.h>
#import "RMPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...        
        RMPerson *person = [[RMPerson alloc] init];
        person.age = 20;
        
        void (^block)(void) = [^ {
            NSLog(@"age is %d",person.age);
        } copy]; // copy操作,从栈中复制到堆中

        [person release];
        NSLog(@"-----------");
    }
    return 0;
}

----------------- RMPerson.h -----------------
#import <Foundation/Foundation.h>
@interface RMPerson : NSObject
@property (nonatomic, assign) int age;
@end

----------------- RMPerson.m -----------------
#import "RMPerson.h"
@implementation RMPerson
- (void)dealloc {
    [super delloc];
    NSLog(@"RMPerson-delloc");
}
@end


// MRC 环境 控制台输出 
2018-07-03 10:49:35.425698+0800 __block的本质[21020:1916302] -----------
Program ended with exit code: 0

从上面的控制台输出可以看出,即使程序结束了,RMPerson都没有释放,这是为什么呢? 因为block做了copy操作,从栈中拷贝到了堆中,此时block强引用了RMPerson,所以保住了RMPerson。
下面我们来看一下,底层c++代码是如何堆中的block是如何保住RMPerson的。


对象类型的auto变量

从上面源码分析,

如果block被拷贝到堆上时
  • 1.会调用block内部的copy函数
  • 2.copy函数内部会调用_Block_object_assign函数
  • 3._Block_object_assign函数会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用。
如果block从堆上移除
  • 1.会调用block内部的dispose函数
  • 2.dispose函数内部会调用_Block_object_dispose函数
  • 3._Block_object_dispose函数会自动释放引用的auto变量(release)
block copy

总结:

当block内部访问了对象类型的auto变量时

1.如果block是在栈上,将不会对auto变量产生强引用

2.如果block被拷贝到堆上

  • 会调用block内部的copy函数
  • copy函数内部会调用_Block_object_assign函数
  • _Block_object_assign函数会根据auto变量的修饰符(__strong、__weak、* __unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用

3.如果block从堆上移除

  • 会调用block内部的dispose函数
  • dispose函数内部会调用_Block_object_dispose函数
  • _Block_object_dispose函数会自动释放引用的auto变量(release)

相关文章

  • block-对象类型的auto变量

    从上些章节block-变量的捕获(caputer)中,详细说了基本类型的auto变量的捕获,现在来了解下,对象类型...

  • Block-对象类型的auto变量

    01 ARC中对象变量在执行完作用域之后并没有被销毁,因为他会有一个强指针指向了原来那个对象,如果我们访问使用下面...

  • iOS底层原理(9)-block-copy属性,auto变量

    对象类型的auto变量 1.当block内部访问了对象类型的auto变量时如果block是在栈上,将不会对auto...

  • 9OC使用原理 -9-block-copy属性,auto变量

    对象类型的auto变量 1.当block内部访问了对象类型的auto变量时如果block是在栈上,将不会对auto...

  • Block:Block 对象类型的auto变量

    Block 对象类型的auto变量 当block内部访问了对象类型的auto变量时 1、如果block是在栈上,将...

  • 对象类型的auto变量

    ?当block内部访问了对象类型的auto变量时如果block在栈上,将不会对auto变量产生强引用 如果blco...

  • Block的引用情况

    当block内部访问了对象类型的auto变量时: 如果block是在栈上的(访问了auto变量的block),将不...

  • iOS:Block(一)

    目录一,本质二,变量捕获三,类型四,对象类型的auto变量 一,本质 1,实例代码 2,底层代码(用clang进行...

  • c++ primer 阅读 day4

    2.5.2 auto 类型说明符 可以从表达式推断出要定义变量的类型, 编译器是将引用的对象的类型作为auto的类...

  • iOS Block(2)-block访问对象类型的auto变量

    前面的block讲解中,block访问的都是基本类型的变量,接下来我们了解一下block访问对象类型的auto变量...

网友评论

    本文标题:block-对象类型的auto变量

    本文链接:https://www.haomeiwen.com/subject/mowluftx.html