**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