iOS底层学习-day-8

前言-OC语法篇

我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。

问题

self在函数中是全局变量还是布局变量?

  • 是全局变量,因为他是函数自带的两个参数self _cmd

block的本质

  • block本质上也是一个OC对象,它内部也有个isa指针
  • block是封装了函数调用以及函数调用环境的OC对象
  • 如下图
    在这里插入图片描述

block变量的截获

  • 全局变量没有捕获,因为全局变量直接可以访问
    在这里插入图片描述
// auto:自动变量,是定义的隐藏关键字,离开作用域(括号)就销毁

auto int age = 10; //等价于 int age = 10;//值传递
static int height = 10;//static修饰的东西,会取地址这个值//指针的传递

void (^block)(void) = ^{
     // age的值捕获进来(capture)
     NSLog(@"age is %d, height is %d", age, height);
};

age = 20;
height = 20;

block();
  • self的捕获
- (void)test {
    void (^block)(void) = ^{
        NSLog(@"-------%p", self);
    };
    block();
}
//因为self _cmd是每个类的隐式参数.所以self有被捕获

- (void)test {
    void (^block)(void) = ^{
        NSLog(@"-------%d", self.name);
    };
    block();
}

block的三种类型

  • 可以通过调用class方法或者isa指针查看具体类型,最终都是继承自NSBlock类型
    • NSGlobalBlock ( _NSConcreteGlobalBlock )全局block
    • NSStackBlock ( _NSConcreteStackBlock )栈block
    • NSMallocBlock ( _NSConcreteMallocBlock )堆block
      在这里插入图片描述
    void (^block)(void) = ^{
        NSLog(@"Hello");
    };
    
    NSLog(@"%@", [block class]);									__NSGlobalBlock__
    NSLog(@"%@", [[block class] superclass]);						__NSGlobalBlock__
    NSLog(@"%@", [[[block class] superclass] superclass]);				NSBlock
    NSLog(@"%@", [[[[block class] superclass] superclass] superclass]);	NSObject

block类型判断

  • 变量的区别
int age = 10;//全局变量

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int a = 10;//局部变量
        
        NSLog(@"数据段:age %p", &age);//全局变量
        NSLog(@"栈:a %p", &a);//局部变量
        NSLog(@"堆:obj %p", [[NSObject alloc] init]);//alloc 和malloc出来
        NSLog(@"数据段:class %p", [MJPerson class]);
     }
}
  • 三种block类型 ARC下
	//block1:__NSGlobalBlock__ ( _NSConcreteGlobalBlock )全局block
	//没有访问外部(auto)变量的为全局block
    void (^block1)(void) = ^{
        NSLog(@"Hello");
    };
    
    //block2:__NSMallocBlock__ ( _NSConcreteMallocBlock )堆block
    //堆[person alloc]或者[person malloc]需要我们手动销毁
    //在ARC下将栈block进行了一次拷贝操作到堆block
    int age = 10;
    void (^block2)(void) = ^{
        NSLog(@"Hello - %d", age);
    };
    
    //block3:__NSStackBlock__ ( _NSConcreteStackBlock )栈block
    //会自动销毁
    NSLog(@"%@ %@ %@", [block1 class], [block2 class], [^{
        NSLog(@"%d", age);
    } class]);

block的copy修饰符

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

    • block作为函数返回值时
    • 将block赋值给__strong指针时
    • block作为Cocoa API中方法名含有usingBlock的方法参数时
    • block作为GCD API的方法参数时
  • MRC下block属性的建议写法

    • @property (copy, nonatomic) void (^block)(void);
  • ARC下block属性的建议写法

    • @property (strong, nonatomic) void (^block)(void);
    • @property (copy, nonatomic) void (^block)(void);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值