**1.block 分配的地址 **
block 大概可以分配到3个地方
NSGlobalBlock(全局的)、NSMallocBlock(堆中)、NSStackBlock(栈中)
**2.下面写个demo详细介绍上面的3个点 **
//
// ViewController.m
// strong weak 的用法
//
// Created by apple on 16/7/5.
// Copyright © 2016年 李重阳. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,assign) int add;
@property (nonatomic,weak) void(^block1)(int);
@property (nonatomic,weak) void(^block2)();
@property (nonatomic,weak) void(^block3)();
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.add = 1;
__weak typeof(self) weakSelf = self;
/*-------------------1.全局的block-----------------------------------------**/
/*1.全局的block**/
/* 只是操作自己的参数 不能操作其他任何的参数 **/
void (^block)(int) = ^(int a) {
NSLog(@"block1:%d", a);
};
NSLog(@"block1_type = %@",block);//block1_type = <__NSGlobalBlock__: 0x10a1be0e0>
/*-------------------2.分配到堆中的block--------------------------------**/
/*
* 2.分配到堆中的block
* 会分配到堆中的block
* 即在arc中默认会将block从栈复制到堆上(arc 中 默认是 __strong 修饰),
* 而在非arc中,则需要手动copy.
* 在arc 中如果 block 中引用了其他的变量 (不管是局部变量还是全局变量),都会拷贝到堆中
**/
void (^block2)(void) = ^{
/*1).这种情况调用的时候还是崩溃**/
//NSLog(@"block2:%d", weakSelf.add);
/*2).这种情况调用的时候还是崩溃**/
// __strong ViewController * strongSelf = weakSelf;
// NSLog(@"block2:%d", strongSelf.add);
/*3).这种情况调用的时候还是崩溃**/
//NSLog(@"block2:%d", self.add);
NSLog(@"block2:%@", self);
/*
* 上面的情况调用崩溃,很可能是 block2 在viewdidLoad 结束后 ,又马上释放掉了
* 但是有个疑问就是 怎么block 里面引用了self 还是不行了呢?
* 在touchesBegan中打印了 self.block2 的值 = null,说明的是 当前的block2 在
* 在viewdidLoad 结束后会马上的释放掉 并且block = nil (所以里面的不管copy 了多少东西都马上清空了);
* 只有全局的block 还是 还是能看到地址
* 栈block 直接崩溃(可能是栈里面的东西 ios 系统没做处理,释放后没有让其值 = nil)
***/
};
NSLog(@"block2_type = %@",block2);//block2_type = <__NSMallocBlock__: 0x7fa9c2418d90>
/*-------------------3.分配到栈中block--------------------------------**/
/*
3.分配到栈中(用__weak 来修饰) ,
这个当在 其他地方调用的时候 很容易崩溃
**/
__weak void (^block3)(void) = ^(){
NSLog(@"block3:%d", weakSelf.add);
};
NSLog(@"block3_type = %@",block3);//block3_type = <__NSStackBlock__: 0x7fff50da8980>
/*-------------------4.测试 --------------------------------**/
/*
* 测试
* 我们用一个weak 的全局block 来引用
* 在touchBegan 中调用
**/
self.block1 = block;
self.block2 = block2;
self.block3 = block3;
/*
在viewdidLoad 里面 都可以 正常的执行 ,但是在touchesBegan: 中就可能出现问题
**/
self.block1(1);//正常运行
self.block2();//正常运行
self.block3();//正常运行
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"self.block1 = %@",self.block1);//<__NSGlobalBlock__: 0x102baf0f0>
NSLog(@"self.block2 = %@",self.block2);//(null)
//NSLog(@"self.block3 = %@",self.block3);//直接崩溃
//self.block1(1);//正常运行
//self.block2();//直接崩溃
//self.block3();//直接崩溃
}
@end
**3.总结 **
1).关于 __weak typeof(self) weakSelf = self;
在block中 __strong ViewController * strongSelf = weakSelf;主要用在第三方的block 中,解释说,是为了防止block 提前释放,同时防止循环引用 ,很想 求一个例子,不写这个和写这个出现不同的结果。到目前为止 我个人理解是没用,没效果(真的很希望求一个例子)。
2)block中 还是用strong 或者copy 拷贝到堆中,不要让其马上释放掉
3)后续 在研究一下block