第04天实战技术(04):Block内存管理(MRC)
2017-03-29 00:00
405 查看
#####一、Block内存管理(MRC)
1.block是存放到栈还是全局区:默认情况是在全局里面访问变量问题:(特殊两种情况:1.
2.在MRC管理下block只能用copy,不能使用retain:
#####二、在MRC的管理下使用
code
官方文档 搜索 : working with Block Blocks are Objective-C objects block : 是不是一个对象? 是(苹果说的) 如何判断当前文件是MRC , 还是ARC 1.dealloc 能否调用super,只有MRC才可以调用super 2.能否使用retain,relese,如果能用就是MRC ARC管理原则 : 只要一个对象没有被强指针修饰 就会被销毁,默认局部变量对象都是强指针,存放到堆里面 MRC了解开发常识 : 1.MRC没有strong weak, 局部变量对象就是相当于基本数据类型(放到栈里面去管理的) 2.给成员属性赋值,一定要使用set方法,不能直接访问下划线成员属性赋值 默认情况下 : block没有使用任何变量. 放到全局区里面. <__NSGlobalBlock__: 0x105be10a0> MRC : 管理block 只要block引用外部局部变量,block放到栈里面.<__NSStackBlock__: 0x7fff5c56f958> block只能使用copy,不能使用retain,使用retain,block还是在栈里面 ARC :
1.block是存放到栈还是全局区:默认情况是在全局里面访问变量问题:(特殊两种情况:1.
访问全局(静态)变量:存在全局区)2.
访问局部变量:存在栈区
//int a = 3; // 全局 - (void)viewDidLoad { [super viewDidLoad]; // MRC // self.name = @"123"; // 这里会走setName方法 (老程序员) _name = @"123"; // 这里不会 setName方法 // 堆、栈、全局区 // block是放在全局区的 (<__NSGlobalBlock__: 0x1048d2080>) // 引用静态变量 static int a = 3; // 总结: // 只要block 代码块中 引用了外部的局部变量 (block 放在栈) // int a = 3; // 只要block 没有引用外部的局部变量, block放在全局区 // block只能使用copy,不能使用retain,block还是在栈里面 #pragma block // static int a = 3; // 全局 // int a = 3; // 局部 __block int a = 3; // 局部 <__NSStackBlock__: 0x7fff59438940> void (^block)() = ^{ NSLog(@"调用了 block %d",a); // 在栈 : <__NSStackBlock__: 0x7fff5c56f958> }; self.block = block; // 使用self.block 赋值 // NSLog(@"%@",block); NSLog(@"%@",self.block); }
2.在MRC管理下block只能用copy,不能使用retain:
在MRC的情况下 block要使用copy,不要使用retain 要不然出现坏的内存访问(在栈里面,说明代码块一过,对象就销毁了,从而出现坏的内存访问)
//@property(nonatomic,retain)void(^block)(); // retain 引用计算+1 放到栈里面 @property(nonatomic,copy)void(^block)(); // copy 引用计算+1 放到全局里面 - (void)viewDidLoad { [super viewDidLoad]; __block int a = 3; // 局部 <__NSStackBlock__: 0x7fff59438940> void (^block)() = ^{ NSLog(@"调用了 block %d",a); // 在栈 : <__NSStackBlock__: 0x7fff5c56f958> }; self.block = block; // 使用self.block 赋值 NSLog(@"%@",self.block); } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { self.block(); // 坏的内存访问 , 在MRC的情况下 block要使用copy,不要使用retain 要不然出现坏的内存访问(在栈里面,说明代码块一过,对象就销毁了,从而出现坏的内存访问) }
#####二、在MRC的管理下使用
self.属性或者
_属性的区别
@property(nonatomic,copy) NSString *name; - (void)setName:(NSString *)name { // 传过来的name 不等于之前的name才需要赋值 if (name != _name) { [_name release]; // 把之前的release _name = [name retain]; // 重新赋值 (retain) } } ----- // self.name = @"123"; // 这里会走setName方法 (老程序员) _name = @"123"; // 这里不会 setName方法
code
/**
block : 是不是一个对象? 是(苹果说的)
如何判断当前文件是MRC , 还是ARC
1.dealloc 能否调用super,只有MRC才可以调用super
2.能否使用retain,relese,如果能用就是MRC
ARC管理原则 : 只要一个对象没有被强指针修饰 就会被销毁,默认局部变量对象都是强指针,存放到堆里面
MRC了解开发常识 : 1.MRC没有strong weak, 局部变量对象就是相当于基本数据类型(放到栈里面去管理的)
2.给成员属性赋值,一定要使用set方法,不能直接访问下划线成员属性赋值
MRC : 管理block
ARC :
*/
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,copy) NSString *name;
//@property(nonatomic,retain)void(^block)(); // retain 引用计算+1 放到栈里面
@property(nonatomic,copy)void(^block)(); // copy 引用计算+1 放到全局里面
@end
@implementation ViewController
- (void)setName:(NSString *)name
{
// 传过来的name 不等于之前的name才需要赋值
if (name != _name) {
[_name release]; // 把之前的release
_name = [name retain]; // 重新赋值 (retain)
}
}
//int a = 3; // 全局 - (void)viewDidLoad { [super viewDidLoad]; // MRC // self.name = @"123"; // 这里会走setName方法 (老程序员) _name = @"123"; // 这里不会 setName方法 // 堆、栈、全局区 // block是放在全局区的 (<__NSGlobalBlock__: 0x1048d2080>) // 引用静态变量 static int a = 3; // 总结: // 只要block 代码块中 引用了外部的局部变量 (block 放在栈) // int a = 3; // 只要block 没有引用外部的局部变量, block放在全局区 // block只能使用copy,不能使用retain,block还是在栈里面 #pragma block // static int a = 3; // 全局 // int a = 3; // 局部 __block int a = 3; // 局部 <__NSStackBlock__: 0x7fff59438940> void (^block)() = ^{ NSLog(@"调用了 block %d",a); // 在栈 : <__NSStackBlock__: 0x7fff5c56f958> }; self.block = block; // 使用self.block 赋值 // NSLog(@"%@",block); NSLog(@"%@",self.block); }
- (void)dealloc
{
[super dealloc];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.block(); // 坏的内存访问 , 在MRC的情况下 block要使用copy,不要使用retain 要不然出现坏的内存访问(在栈里面,说明代码块一过,对象就销毁了,从而出现坏的内存访问)
}
@end
相关文章推荐
- 第04天实战技术(05):Block内存管理(ARC)
- 第04天实战技术(06):Block循环引用
- 第04天实战技术(07):Block变量传递
- 第04天实战技术(09):block开发中使用场景(返回值)
- 第04天实战技术(02):block开发使用场景(代理传值)
- 第04天实战技术(01):block开发使用场景(保存代码)
- 第04天实战技术(08):Block开发使用场景(参数使用)
- 第04天实战技术(03):block开发使用场景(传值)
- 黑 马 程 序 员_视频学习总结<Objective-C>----04 内存管理、protocol、block、ARC
- 第04天实战技术(15):UICollectionView计算布局尺寸
- block的理解与 MRC,ARC下内存管理
- 第04天实战技术(16):UICollectionView定位
- 第03天实战技术(04):scrollView额外滚动区域
- 第04天实战技术(13):UICollectionView基本使用(抽取方式2)
- 第04天实战技术(10):UICollectionView基本使用
- 第04天实战技术(14):UICollectionView自定义布局方法
- 第02天实战技术(04):runtime字典转模型
- 第01天实战技术(04):iOS9新特性之泛型(协变和逆变)
- 第04天实战技术(11):UICollectionView基本使用(布局)
- 服务端开发指南与最佳实战 | 数据存储技术 | MySQL(04) 索引使用的注意事项