02ARC內(nèi)存管理原則_Foundation和CoreFoundation_全局變量_屬性關(guān)鍵字使用_ARC與MRC的混編_Block_循環(huán)引用_enumerate遍歷_倒序遍歷

一、ARC
(一)基本原理
項(xiàng)目:ARC0427
1.MRC:Manual Reference Counting 手動(dòng)引用計(jì)數(shù)
手動(dòng)添加retain、release、autorelease、super dealloc

2.ARC:Automatic Referenc Counting 自動(dòng)引用計(jì)數(shù)
ARC內(nèi)存管理原則:
1)有強(qiáng)引用指針指向的對(duì)象,不會(huì)被釋放掉
2)若沒有,就會(huì)被立刻釋放。

3.關(guān)鍵字的使用
1)系統(tǒng)在編譯時(shí)自動(dòng)添加retain、release、autorelease、super dealloc
2)禁用retain、release、autorelease、super dealloc

使用新關(guān)鍵字strong、weak、unsafe_unretain(不常用)、__bridge
 (1) strong:強(qiáng)引用,會(huì)對(duì)對(duì)象引用計(jì)數(shù)+1。出了作用域,就會(huì)被釋放。
 (2) weak,(不常用)unsafe_unretain:弱引用,對(duì)引用計(jì)數(shù)無+-。
   weak:立即被釋放。當(dāng)對(duì)象釋放,指針會(huì)指向nil,不會(huì)造成程序崩潰
   unsafe_unretained(不常用):當(dāng)對(duì)象釋放,指針仍指向被釋放對(duì)象的內(nèi)存,程序會(huì)崩潰
 (3) __bridge:用于 對(duì)OC類型與CF類型 互相轉(zhuǎn)換時(shí)的內(nèi)存管理。

特點(diǎn):
①在ARC中使用
②不會(huì)改變ownership(內(nèi)存管理權(quán)限)
方法:CFBridgingRetain
特點(diǎn):交換管理權(quán)限
注意:聲明變量時(shí),默認(rèn)是strong

4.Foundation 和 CoreFoundation
1)概念
Foundation框架:定義了常用的數(shù)據(jù)類型(如OC對(duì)象 NSString、NSData、NSSet等)。
CoreFoundation框架:定義了與系統(tǒng)底層API打交道的數(shù)據(jù)類型(CF開頭的類型)。
2)區(qū)別
OC類型 與 CF類型 在內(nèi)存結(jié)構(gòu)上是相同的,即同一塊內(nèi)存地址上有兩個(gè)不同的名字(NS,CF
3)轉(zhuǎn)換
ARC下,OC與CF 要使用關(guān)鍵字__bridge 進(jìn)行轉(zhuǎn)換
MRC下,OC與CF 可直接進(jìn)行 強(qiáng)制類型轉(zhuǎn)換

(二)
項(xiàng)目:ARC_More0427
1.__autoreleasing:不常用,系統(tǒng)會(huì)自動(dòng)添加
2.@autoreleasepool{}:不常用,可以替換 MRC 中的 NSAutoreleasePool
在局部大量創(chuàng)建自動(dòng)釋放的對(duì)象時(shí)(如for循環(huán)),會(huì)使用自動(dòng)釋放池。
3.移除通知:自定義類的對(duì)象被注冊(cè)為監(jiān)聽者時(shí),當(dāng)該對(duì)象被釋放時(shí),在該類的dealloc方法中移除通知
4.局部、實(shí)例、全局變量
1)局部變量:出了作用域就會(huì)被釋放
2)實(shí)例變量:dealloc中釋放
3)全局變量:程序退出時(shí)系統(tǒng)自動(dòng)收回
在整個(gè)應(yīng)用程序中都可以使用,程序退出時(shí),才被釋放。系統(tǒng)管理內(nèi)存。

//①聲明:
#import "AppDelegate.h"
NSString *text = @"全局變量";
//②引入:
#import "ViewController.h"
extern NSString *text;

5.屬性關(guān)鍵字的使用
1)基本數(shù)據(jù)類型:assign(或省略)
2)字符串:copy
3)對(duì)象:strong(等同于MRC中的retain)
4)代理:weak(防止循環(huán)引用)
5)控件
①拖拽:默認(rèn)為weak(也可以使用strong,但沒有必要)
原因:self.view已經(jīng)使用了strong關(guān)鍵字,所以沒有必要對(duì)拖拽的控件使用strong,用weak即可。
②手動(dòng):strong

6.ARC與MRC的混編
1)ARC環(huán)境下:使用第三方類庫(kù)(不支持ARC),在每個(gè)文件上加 -fno-objc-arc
2)MRC環(huán)境下:使用第三方類庫(kù)(只支持ARC),在每個(gè)文件上加 -fobjc-arc
舉例:
weak

    __weak UIView *view1 = [[UIView alloc]initWithFrame:CGRectZero];
    NSLog(@"1.view1 = %@",view1);//被立即釋放
    {
        UIView *view2 = [[UIView alloc]initWithFrame:CGRectZero];//strong
        view1 = view2;//只要有一個(gè)strong,view1就不會(huì)釋放
        NSLog(@"2.view1 = %@",view1);
    }//view2被釋放,即view2 = nil;view1也為nil
    NSLog(@"3.view1 = %@",view1);

二、Block
(一)
項(xiàng)目:Block_Define0427
一、局部block對(duì)象 定義格式
1.聲明

void(^blockName)(parameter list)

①無參無返回值
②有參無返回值
③有參有返回值

    float(^calculateBMI)(float,float);

2.實(shí)現(xiàn)

blockName = ^(parameter list){ myCode };
    calculateBMI = ^(float weight,float height)
    {
        float BMI = weight / (height *height);
        return BMI;
    };

3.調(diào)用

blockName(parameter list);
    float bmi = calculateBMI(70,1.7);

(二)block內(nèi)部使用外部變量
項(xiàng)目:Block_UseOutPamater
1.局部變量
1)普通局部變量
相當(dāng)于copy了一個(gè)新的變量,值和原來的一樣,
block內(nèi)只讀,與外部的i是兩個(gè)不同的變量

int i = 1;

2)使用__block關(guān)鍵字
block內(nèi)可修改,與外部的i是同一變量

__block int block_i = 1;

2.實(shí)例變量和靜態(tài)變量
block是從變量所在的內(nèi)存地址中讀取最新的值
可修改

(三)
項(xiàng)目:Block_MRC_Memory
1.MRC下的內(nèi)存分配
1)不使用外部變量
NSGlobalBlock類型,分配在全局變量區(qū),由系統(tǒng)收回
2)使用外部變量
NSStackBlock類型,分配到棧區(qū)
該block出了作用域,就由系統(tǒng)釋放。
3)對(duì)分配在棧區(qū)的block進(jìn)行Block_copy操作
NSMallocBlock類型,分配在堆區(qū)
程序員只要不調(diào)用Block_release(...)方法,block就始終存在
2.ARC下的內(nèi)存分配
系統(tǒng)會(huì)對(duì)棧上的block進(jìn)行一次copy,拷貝到堆區(qū),由NSStackBlock--->NSMallocBlock
使用外部變量
NSMallocBlock類型
(四)
項(xiàng)目:Block_MRC_Memory

 UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
    void(^block1)() = ^()
    {
        view.backgroundColor = [UIColor redColor];
    };
    Block_copy(block1);//copy方法只對(duì)棧區(qū)的block有用

使用Block_copy使block1變?yōu)槎褏^(qū)
分配在堆上的block會(huì)對(duì)外部變量的引用計(jì)數(shù)+1
當(dāng)block釋放時(shí),它內(nèi)部使用的外部變量的引用計(jì)數(shù)會(huì)隨之-1

造成循環(huán)引用:
block釋放時(shí),self.retainCount會(huì)-1
self釋放時(shí),block才會(huì)釋放(在self的dealloc方法中釋放)

防止循環(huán)引用:
在MRC環(huán)境中,使用__block修飾外部變量
在ARC環(huán)境中,使用__weak修飾

(五)
項(xiàng)目:Block_TransformValue0427
1.遍歷
1)遍歷數(shù)組

    NSArray *array = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8"];
    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSLog(@"obj%d = %@",idx,obj);
        if (idx == 4)
        {
            *stop = YES;//停止循環(huán)
        }
    }];

2)倒序遍歷

    [array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    }];

2.傳值

測(cè)試:alertView傳值,用block

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容