亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

黑馬程序員--Objective-C內存管理我之見解

2019-11-14 18:32:40
字體:
來源:轉載
供稿:網友

------<a target="blank">java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! -------

內存管理

為什么要進行內存管理?
因為設備的內存空間是有限的,如果一直占用,而不回收空間,內存就會被一直占用,導致內存不足,  系統就會就會報警,嚴重的可能直接退出程序,因此,在軟件開發過程中,需要進行內存管理,以保證高效快速的分配內存,并且在適當的時候釋放和回收內存資源。
 
內存管理的范圍?
任何繼承了NSObject的對象,對基本數據
類型無效,主要對堆區的內存進行管理。
 
為什么要對堆區的內存空間進行管理,基本數據類型不需要管理呢?
因為基本數據類型的數據會被放入棧中,他們依次緊密排列,遵循先進后出的原則,系統會自動進行管理。 而對象類型會被放到堆中,堆中的內存是不連續的,無法自動釋放,所以需要我們管理。
 
內存管理的原理?
(1)對象的所有權及引用計數器
      對象的所有權:任何對象都有一個或多個擁有者,只要一個對象至少還有一個擁有者,他就不會被釋放
(2) 任何自己創建的對象都歸自己所有,可以使用alloc和new開頭或名字中包含copy的方法創建對象,使用return來獲得一個對象的所有權。
(3) OC中都有專門8個字節的存儲空間來存儲引用計數器,用整數表示對象被引用的次數。
引用計數器是判斷對象是否回收內存空間的依據。
(4) 給對象發送消息
         return  計數器+1,方法返回對象本身
         release  計數器-1,但不代表釋放,autorelease 也可使引用計數器-1.
         retaincount消息  用來獲得當前引用計數器的值 
 
引用計數器為0,系統像對象發送dealloc消息,(調用[super dealloc]方法,一定要寫在后面)釋放相關資源,對象被回收后將不能在被使用(僵尸對象),僵尸對象不可復活,否則會導致程序崩潰,導致野指針錯誤
 
如何防止野指針錯誤,在對象被釋放后賦值為nil.
 
內存管理的分類?
MRC 手動內存管理
ARC 自動內存管理
垃圾回收   iOS不支持
 
內存管理的原則?
如果還有人使用某個對象,這個對象就不會被回收。
如果有人想使用這個對象 那么就應給讓對象的引用計數器+1
如果不想使用這個對象,就有那個該讓對象的引用計數器-1
誰創建誰relesase   誰retain 誰release.有始有終 有加有減。
 
內存研究的內容?
野指針 內存泄露
野指針 定義的指針變量沒有初始化。指向的空間已經被釋放
內存泄露 :如果棧區的的空間已經被釋放了,而堆區的空間還沒與被釋放,堆區的空間就被泄露了。 

 

 

 單個對象內存管理

  1. 野指針錯誤:

      訪問了一塊壞的內存

  2. 僵尸對象:

      如果一個對象已經被釋放,這個對象被稱為僵尸對象

  3. 空指針:

      沒有指向任何東西的指針,給空指針發送消息不會報錯

  4. nil和NULL的區別

     nil  對象指針

     NULL 類對象指針

   5. 避免使用僵尸對象的方法:

      對象釋放了以后,給對象賦值為nil

   6. 單個對象的內存泄露

      情況1: 創建完成,使用之后,沒有release

 

情況2: 沒有遵守內存管理原則

 

        Dog *d = [[Dog alloc] init]

 [d retain];

 

      情況3: 不當的使用了nil

 

Dog *d = [[Dog alloc] init]

 

   d = nil;

 

      情況4:  在方法中對傳入的對象進行了retain

 

Dog *d = [[Dog alloc] init]

 

[d compareColorWithOther: d];

 

 

基本數據類型set方法的寫法    直接賦值

  

     -(void)setSpeed:(int)speed{ _speed = speed;}

 

 

對于對象作為另外一個類的實例變量

  

  -(void)setDog:(Dog *)dog{if(_dog!=dog){   //先判斷是不是原來的對象[_dog release];  //不是原來的對象做一次release,_dog = [dog retain];}}
 

@PRoperty 參數
格式:@property (參數1,參數2) 數據類型 方法名 

1.是否要生成set方法

readwrite : 同時生成setter和getter的聲明、實現

readonly :只會生成getter的聲明和實現

2.多線程管理

nonatomic :性能高(一般用這個)

atomic :性能低(默認)

3.set管理相關參數

retain :release舊值,return新值(適用于oc對象類型)

assign : 直接賦值(默認,適用于非OC對象)

copy : release舊值,copy新值
 
(1)  assign 直接賦值

  -(void)setCar:(Car *)car{

_car =car;

}

(2)  retain  release舊值,再retain新值

在一個類中有關聯其他對象的時候,這個對象的      @property(nonatomic,assign)  數據類型  方法名

     -(void)setCar:(Car *)car{if(_car!=car){   //先判斷是不是原來的對象[_car release];  //不是原來的對象做一次release,_car = [car retain];}}

 

 

(3) 是否要生成set方法(若只讀,則不生成)

readonly :只讀,只會生成getter的聲明和實現

readwrite:默認的,同時生成setter和getter的聲明和實現

(4)多線程管理

    @property(nonatomic,assign)  數據類型  方法名

   高性能,一般使用nonatomic

(5)  set和get方法的名稱

修改set和get方法的名稱,主要用于布爾類型。因為返回布爾類型的方法名一般以is開頭,修改名稱一般用 在布爾類型中的getter 

 

//替換set方法名稱  @property(nonatomic,assign ,setter= isVip:) //替換get方法名稱  @property(nonatomic,assign ,getter = isVip)//替換set,get方法名稱  @property(nonatomic,assign ,setter=isVip,getter = isVip:)  

 

 

 

 

循環retain問題

會導致兩個對象都會內存泄露

防止方法:

1) 讓某一個對象多釋放一次(注意順序) 

2) 推薦方法: 一端使用assign 一端使用retain

Dog.h#import <Foundation/Foundation.h>//#import "Person.h"@class Person;@interface Dog : NSObject//狗有個主人@property (nonatomic,retain) Person *owner;//這里用retain@endDog.m#import "Dog.h"#import "Person.h"@implementation Dog- (void)dealloc{    [_owner release];  //    NSLog(@"Dog dealloc");    [super dealloc];}@endPerson.h#import <Foundation/Foundation.h>//#import "Dog.h"@class Dog;@interface Person : NSObject//人擁有一條狗@property (nonatomic,assign) Dog *dog;//這里用assign@endPerson.m#import "Person.h"#import "Dog.h"@implementation Person- (void)dealloc{    //    [_dog release];  //nil這里不在需要    NSLog(@"Person dealloc");    [super dealloc];}@endmain.m    #import <Foundation/Foundation.h>#import "Dog.h"#import "Person.h"int main(int argc, const char * argv[]) {    @autoreleasepool {                Person *p = [Person new];  //1        Dog *d = [Dog new];   //1                //人有一條狗        p.dog = d;    //  d   1        d.owner = p;  //  p   2                [p release];  //0        [d release];  //        //        [d release];       //        [p release];            }    return 0;}                                                                                                                                                                                            

 

 

類方法不需要管理內存

autorelease基本使用

一個對象調用autorelease,將這個對象放到位于棧頂得的釋放池

@autoreleasepool

{  //   

}

概念介紹:  一種支持引用計數器的內存管理方式,可以暫時保存某個對象,然后再內存池自己的排干的時候對其中的每個對象發送release消息

好處:  不用擔心對象釋放時間,也不用擔心什么時候調用release

原理:

      autorelease實質上只是把對release的調用延遲了,對于每一個autorelease,該Object放入了當前的Autoreleasepool中,當該pool釋放時,該pool中的所有Object都會被調用release;

 

自動釋放池: 特殊的棧結構(數據結構),和內存的棧區結構不同

特點: 對象可以加入到自動釋放池中,自動釋放池結束的時候,會給釋放池中的每個對象發送一條release消息

使用:

1)自動創建釋放池

autoreleasepool{

}

2)加入自動釋放池,

在自動釋放池中

[對象 autorelease]

加入到自動釋放池中以后,引用計數器不會變化

 

基本用法總結

1.會將對象放到一個自動釋放池中

2.當自動釋放池被銷毀時,會對尺子里的所有對象做一次release操作

3.會返回對象本身

4.調用完autorelease方法后,對象的計數器不變。

 

int main(int argc, const char * argv[]) {    //1 創建自動釋放池    Person *p = [Person new];  // p  1    @autoreleasepool {//自動釋放池開始                [p run];         NSLog(@"%lu",p.retainCount); // 1                // [p autorelease] 把對象p加入到自動釋放池中        // 注意:加入到自動釋放池中以后, 引用計數不會變化        [p autorelease];  //加入自動釋放池,        NSLog(@"%lu",p.retainCount); // 1                [p run];            }//自動釋放池結束   [p release];    [p run];    return 0;}

 

 

 

注意及錯誤用法:

1)并不是放到自動釋放池中的代碼產生的對象就會自動釋放,如果需要釋放,必須自動加入到自動釋放池

2)如果對象調用了autorelease但是調用autorelease的時候,沒有在任何一個自動釋放池中,此時該對象也不會被加入到自動釋放池

3)我們只需要在自動釋放池代碼塊中調用autorelease就可以把對象加入到自動釋放池

4)內存較大盡量不要使用autorelease

 

自動釋放池嵌套使用

 

為什么內存管理只管理內存對象?

堆中內存不連續,無法自動釋放!

 

我們如何對內存對象進行管理!

通過操作對象的引用計數器

 

autorelease的應用場景 

經常用來在類方法中快速創建一個對象

 

 
ARC
指針分類
(1)強指針:默認情況下所有指針都是強指針  關鍵字__strong
(2)弱指針:__weak關鍵字修飾的指針
 
原則 :當開啟ARC時,編譯器將自動在代碼合適的地方插入retain、release、autorelease.
          永遠不要寫retain、release、autorelease;
 
判斷準則:只要沒有強指針,對象就會被釋放
 
ARC機制:

1)判斷是否是ARC機制

查看項目信息,不能使用retain release和autorelease,retainCount ,不能調用[super dealloc]

2)使用

正常創建對象,不用手動釋放對象

ARC下單對象內存管理

  ARC機制下,對象沒有被強指針指向,對象會立即釋放空間

(兩個下劃線)__strong 修飾的指針是強指針,可以不寫 

                 __weak 修飾的指針是弱指針

 1) 強指針指向了其他內容,對于對象來說就沒有強指針指向了

 2) 弱指針賦值為nil

 

ARC下多對象的內存管理 

 

ARC機制下不能使用retain 應該使用strong 和 weak

ARC下循環引用問題

循環引用時一端使用strong , 一端使用weak.

 

ARC下set方法內存和@property參數

  原子性/讀寫 和MRC下一樣

 MRC            ARC

assign         assign 適用于非oc對象

retain         strong(強指針) OC的其他對象  weak (成員變量是弱指針適用于oc對象)

copy            copy

 

ARC使用特點及注意事項

  特點: 

1) 不允許調用retain release、retainCount

2) 允許重寫dealloc,但是不能調用[super dealloc] 

 

注意事項:

  1)ARC中,只要弱指針對象不存在,直接把弱指針清空(賦值nil)操作

  2)__weak Person *p = [Person new]

弱指針指向空間銷毀過程: (1)釋放對象空間  (2)指針賦值nil

 

 

 

 

MRC轉換為ARC

edit->Refactor->convert to Objective-C ARC…簡單代碼

ARC兼容非ARC的類

 轉變為非ARC   -fno-objc-arc

 轉變為ARC的    -f-objc-arc

 

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美另类第一页| 最近日韩中文字幕中文| 日韩毛片在线观看| 亚洲乱亚洲乱妇无码| 精品亚洲一区二区三区四区五区| 久久免费视频网站| 欧美色视频日本高清在线观看| 中文字幕九色91在线| 亚洲精品狠狠操| 在线亚洲国产精品网| 欧美丝袜一区二区| 国产精品视频一区二区高潮| 国产精品极品美女粉嫩高清在线| 狠狠躁18三区二区一区| 91在线视频一区| 性色av一区二区三区红粉影视| 日韩免费在线电影| 久久精品国产综合| 亚洲bt欧美bt日本bt| 在线视频精品一| 538国产精品一区二区在线| 亚洲欧美www| 亚洲精品欧美日韩专区| 亚洲电影免费观看高清完整版| 国产在线观看91精品一区| 日韩日本欧美亚洲| 欧美电影免费观看| 国产精品第3页| 丝袜亚洲另类欧美重口| 成人免费网视频| 亚洲视频777| 日韩在线精品一区| 精品中文字幕久久久久久| 色中色综合影院手机版在线观看| 欧美成aaa人片免费看| 精品自在线视频| 黑人欧美xxxx| 日韩女优在线播放| 97在线观看视频| 国产精品亚洲第一区| 欧美日韩国产精品一区二区三区四区| 91中文精品字幕在线视频| 亚洲自拍高清视频网站| 国产精品欧美激情在线播放| 在线电影av不卡网址| 亚洲乱码国产乱码精品精| 91sao在线观看国产| 国产亚洲视频在线观看| 668精品在线视频| 欧美日韩色婷婷| 成人福利在线观看| 欧美专区在线观看| 日韩精品日韩在线观看| 午夜免费在线观看精品视频| 美女视频黄免费的亚洲男人天堂| 精品五月天久久| 狠狠做深爱婷婷久久综合一区| 丝袜美腿亚洲一区二区| 亚洲精品久久久久久久久久久久久| 欧美日韩另类在线| 国产欧美精品xxxx另类| 亚洲欧美国内爽妇网| 国产精品伦子伦免费视频| 97在线视频免费观看| 国产美女被下药99| 亚洲精品xxx| 日韩电影第一页| 欧美另类老肥妇| 国产亚洲视频在线观看| 日本精品va在线观看| 国产精品狠色婷| 国产精品国产三级国产aⅴ浪潮| 一本一本久久a久久精品牛牛影视| 欧美日韩一区免费| 国产精品美女呻吟| 欧美国产亚洲精品久久久8v| 亚洲精品自拍第一页| 国产精品91一区| 疯狂做受xxxx欧美肥白少妇| 91九色国产社区在线观看| 欧美激情一区二区三区久久久| 欧美一区二区三区免费视| 日本欧美黄网站| 91在线中文字幕| 欧美一级淫片播放口| 色综合导航网站| 亚洲性xxxx| 国产在线不卡精品| 亚洲一区中文字幕在线观看| 不卡伊人av在线播放| 亚洲高清久久久久久| 亚洲免费电影在线观看| 这里只有精品在线播放| 国产97在线播放| 亚洲理论片在线观看| 日韩精品在线免费观看| 国产精品久久久久久久久久| 国产成人拍精品视频午夜网站| 国产精品96久久久久久又黄又硬| 亚洲级视频在线观看免费1级| 国产精品美女网站| 久久久久久久国产精品视频| 欧美巨乳在线观看| 国产精品主播视频| 亚洲一区二区三区在线免费观看| 国产精品欧美一区二区三区奶水| 亚洲激情视频在线观看| 成人www视频在线观看| 中文字幕精品在线视频| 日韩在线视频导航| 色吧影院999| 日韩精品中文字幕久久臀| 国产精品一二区| 久久精品成人一区二区三区| 亚洲国产成人精品一区二区| 亚洲图片欧美午夜| 中文字幕日韩av电影| 日韩av影视在线| 色综合伊人色综合网站| 久久久久久久久久国产| 久久免费成人精品视频| 精品国产福利在线| 亚洲欧美999| 国内精品久久久久久久久| 欧美激情综合亚洲一二区| 精品免费在线视频| 国产精品久久久久久久久久| 欧美在线视频网站| 亚洲精品乱码久久久久久金桔影视| 欧美午夜精品久久久久久久| 精品久久久久久久久久久久久| 国产精品久久久久999| 精品五月天久久| 日韩av在线一区| 色偷偷9999www| 久久中文字幕国产| 国产精品高潮呻吟久久av黑人| 亚洲xxxxx电影| 日本精品免费一区二区三区| 欧美精品性视频| 国产精品人成电影在线观看| 国产欧美在线看| 欧美电影免费看| www国产91| 欧美xxxx综合视频| 26uuu亚洲国产精品| 久久琪琪电影院| 成人444kkkk在线观看| 欧美成人激情图片网| 91久久综合亚洲鲁鲁五月天| 亚洲国产高潮在线观看| 欧美丰满老妇厨房牲生活| 国产精品色悠悠| 国产91色在线播放| 在线观看欧美www| 亚洲色图校园春色| 91免费版网站入口| 成人网在线观看| 国产精品美女免费视频| 亚洲精品国精品久久99热一| 高清一区二区三区日本久| 91精品国产高清自在线| xvideos成人免费中文版| 精品一区二区三区四区|