您的位置:首页 > 移动开发 > Objective-C

第04天实战技术(04):Block内存管理(MRC)

2017-03-29 00:00 405 查看
#####一、Block内存管理(MRC)

官方文档 搜索 : 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息