发布网友 发布时间:2022-05-26 14:03
共1个回答
热心网友 时间:2023-10-21 00:09
block在ARC和MRC中的声明引用有些区别.
/**
block可以存储在栈中,也可以在堆中
默认存储在栈中,不需要管理内存
存储在堆中的block会对block进行retain操作
*/
//(MRC)block在堆中时,不想对block进行retain操作,前面加__block
//(ARC)前面加__weak或__unsafe_unretained
//__weak和__unsafe_unretained的区别:__weak则在释放时会对对象赋值nil,后者不会
//Block_copy使栈中的block转移到堆中,并对block会引用的对象进行retain操作
//避免block引用的对象进行retain操作,在引用对象声明时前面加__block
dog.h (NSObject类)
//block用copy来定义,这样block存在于堆中
//如果block不是copy到堆中,引用完了对象还在,但block被释放了
[objc] view plain copy print?
#import <Foundation/Foundation.h>
@interface dog : NSObject
@property (nonatomic, assign) int age;
@property (nonatomic, copy) void (^myBlock)();
@end
2.dog.m
//引用self.age会使retainCount = 2的
//因此以__block typeof(self) mySelf = self;方式重新定义self
2.1 在block nslog中不调用d.age情况下,不需要重新定义self
2.2 在block nslog中调用d.age情况下,需要重新定义self
[objc] view plain copy print?
#import "dog.h"
@implementation dog
- (instancetype)init {
if (self = [super init]) {
self.age = 10;
self.myBlock = ^{
NSLog(@"%d",mySelf.age);
};
}
return self;
}
- (void)dealloc {
NSLog(@"dog - dealloc");
//对定义时copy的block进行释放
Block_release(self.myBlock);
[super dealloc];
}
@end
3.main.m文件
[objc] view plain copy print?
int main(int argc, const charchar * argv[]) {
//3.1 block在ARC和MRC中的情况
blockARC_MRC();
//3.2 copy block情况
copyBlock();
return 0;
}
3.1 block在ARC和MRC中的情况
/**
block可以存储在栈中,也可以在堆中
默认存储在栈中,不需要管理内存
存储在堆中的block会对block进行retain操作
*/
//(MRC)block在堆中时,不想对block进行retain操作,前面加__block
//(ARC)前面加__weak或__unsafe_unretained
//__weak和__unsafe_unretained的区别:__weak则在释放时会对对象赋值nil,后者不会
//Block_copy使栈中的block转移到堆中,并对block会引用的对象进行retain操作
//避免block引用的对象进行retain操作,在引用对象声明时前面加__block
[objc] view plain copy print?
void blockARC_MRC(){
__block dog *d = [[dog alloc] init];
d.age = 12;
NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
void (^myBlock)() = ^() {
NSLog(@"d.age = %d",d.age);
};
NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
Block_copy(myBlock);
NSLog(@"block copy后:d retainCount = %zd",d.retainCount);
Block_release(myBlock);
NSLog(@"block release后:d retainCount = %zd",d.retainCount);
myBlock();
NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
[d release];
}
3.2 block中引用成员变量情况
// 1.没有调用d.age时,不需要__block
// 2.调用d.age时.必须要__block
[objc] view plain copy print?
void copyBlock() {
__block dog *d = [[dog alloc] init];
d.age = 12;
NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
d.myBlock = ^{
NSLog(@"myBlock -- %d",d.age);
};
NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
d.myBlock();
NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
[d release];
}
-- end