一妨托、循環(huán)引用兰伤,
以兩個實例為例敦腔,循環(huán)引用產(chǎn)生于兩個實例都強引用的對方符衔,而兩個實例的釋放都依賴于對方的釋放判族,最終都無法釋放形帮。
1.delegate修飾成了strong辩撑,
2.block引起合冀。
block引起循環(huán)引用要注意峭判,block也是一個對象朝抖,當(dāng)block被對象A持有治宣,在block代碼塊中直接調(diào)用對象A相當(dāng)于block對象強引用了對象A侮邀。舉兩個第三方庫對比看看绊茧,
Masonry:
[buttonA mas_makeConstraints:^(MASConstraintMaker*make){
make.width.equalTo(@100);
make.height.equalTo(@100);
make.left.equalTo(self.view.mas_left);
make.top.equalTo(self.view.mas_top);
}];
這里直接用self是因為這個block沒有被持有,執(zhí)行完就被釋放了亡笑,看源碼可知
-(NSArray*)mas_makeConstraints:(void(^)(MASConstraintMaker*))block{
self.translatesAutoresizingMaskIntoConstraints=NO;
MASConstraintMaker*constraintMaker=[[MASConstraintMakeralloc]initWithView:self];
block(constraintMaker);
return[constraintMakerinstall];
}
AFNetworking:
AFNetworking源碼可知,其內(nèi)部使用了嵌套結(jié)構(gòu),以保證在回調(diào)的時候不會已經(jīng)被釋放晰甚,類似這樣
__weakNSObject*weakSelf =self;
void(^block)(void) = ^{
//NSLog(@"b_name = %@",b_name);
__strongNSObject*strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
NSLog(@"b_name = %@",strongSelf);//此處即為回調(diào)
});
};
block();
二、NSTimer
NSTimer *tt ?=[NSTimerscheduledTimerWithTimeInterval:1target:self selector:@selector(timerMethod:)userInfo:nilrepeats:YES];
[tt fire];
這種方式直接創(chuàng)建的timer,將target設(shè)置成self,會導(dǎo)致之self的釋放依賴于timer的終止∫锼伲可以用weakSelf代替洒宝,timer還是要主動invalidate雁歌。
三靠瞎、UIImage加載圖片
[UIImage imageNamed:@""]的方式當(dāng)加載時會緩存圖片乏盐,圖片如果使用頻繁可以用這種,否則推薦使用imageWithContentsOfFile何吝。
四爱榕、C對象的創(chuàng)建和釋放
例如CoreFoundation對象 : 函數(shù)中用create\new\copy\retain產(chǎn)生的對象, 不用的時候需要調(diào)用CFRelease或者其他release函數(shù),將其釋放掉。使用一些ffmpeg,opencv2等底層第三方的時候尤其要注意這一點坑夯。