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