您的位置:首页 > 其它

对于Block的一些理解与认识

2015-08-13 10:36 381 查看
//
//  ViewController.m
//  BlockTest
//
//  Created by CoderHJChao on 8/13/15.
//  Copyright (c) 2015 CoderHJChao. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
{
NSString *_name; // 名字
}
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
/* 1.简单为block赋值
_testBlock = ^(id sender)
{
NSLog(@"我是全局block类型,__NSGlobalBlock__");
};
*/

/* 2.ARC上引用外部变量
int i = 100;
_testBlock = ^(id sender)
{
NSLog(@"我是堆block类型, i%d,__NSMallocBlock__",i);
};

NSLog(@"block %@",^(id sender)
{
NSLog(@"我是堆block类型, i%d,__NSMallocBlock__",i);
});

NSLog(@"block %@",_testBlock);
*/

/* 3.MRC上引用外部变量
int i = 100;
_testBlock = [^(id sender)
{
NSLog(@"我是栈block类型, i%d,__NSStackBlock__",i);
} copy];
*/

/* 4.ARC上引用外部变量*/
//    __block ViewController *weakSelf = self;

__block typeof(self) weakSelf = self;
_testBlock = ^(id sender)
{
[weakSelf setStringName:@"nana"];
};

/*
总结:
1.block是一个对象,因为它也有OC里面的isa指针
2.block是匿名函数,它是基于C的函数拓展,它是一个函数指针
3.block是通过闭包传值,用于异步处理及方法回调、
4.block在内存中分三种类型,分别是 全局block,堆block,栈block

4.1 如果block没有引用外部变量的时候是全局block(__NSGlobalBlock__)

4.2 如果引用外部变量的话,block的初始化是在栈上,
一般我们在ARC上使用的Block是堆block(__NSMallocBlock__),因此在ARC上编译器自动把block拷贝到堆上

4.3 如果引用外部变量的话,block的初始化是在栈上,
我们在MRC上使用的Block就是栈block(__NSStackBlock__),如果block出了栈的作用域外,block就会被自动释放。如果要在堆作用域中使用block,必须要把block手动拷贝到堆上

5. block 容易导致循环引用
因为外部对象引用了block,block内部又引用外部对象,所以导致循环引用。
解决方法:在ARC上,我们可以使用weak关键字作为破解循环引用;但在MRC上,我们可以用__block关键字破解循环引用; 可以让block弱引用内部的变量,从而在释放的时候先断开弱引用,在释放block与外部的

Strong 跟 weak的区别是什么?
strong引用,引用计数加一,两个对象生命周期就会绑定在一起

*/
}

// 改变全局变量
- (void)setStringName:(NSString *)name
{
_name = name;
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"%@",_testBlock);
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: