ios基礎之 透過頁面跳轉來認識 Strong 與 Weak

來源:互聯網
上載者:User

標籤:

   最近在自己做一個小程式,遇到了頁面跳轉的問題,然後上網一通亂搜,跳轉的問題解決了,又有傳值的問題。上面兩個問題解決了,又發現記憶體比剛開始時多佔用了2M,於是,各種內心糾結,想徹底

搞清楚strong 和 weak 在ARC下到底是怎麼個意思,也順便理清了頁面跳轉之間的一些聯絡。

 

  下面開始進入正題:(程式使用了storyboard)

由於頁面中使用了一個動態載入的tableview,所以沒法在頁面中拖segue來實現頁面跳轉,那麼只能在代碼中實現頁面跳轉了。

下面上一下頁面跳轉的小片段:

頁面A的控制器代碼 標頭檔

1 @interface BKViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>2 @property (weak, nonatomic) IBOutlet UITableView *tableview1;3 4 @property (strong, nonatomic) UIViewController *checkFT;5 @property (weak, nonatomic) UIViewController *checkFTWeak;6 @end

標頭檔中定義了3個屬性,

第一個屬性就是對應頁面上的一個tableview沒什麼好說的了。

第二個屬性:一個strong  的頁面B的控制器變數

第三個屬性:一個weak    的頁面B的控制器變數

具體幹什麼,稍後再說

 1 @interface BKViewController () 2 { 3     BOOL _isRegistNib; 4     NSDateFormatter *_shortDateFormatter; 5     NSArray *tableData; 6      7     NSArray *kpType;//記賬類型 8     int pushCount;//紀錄跳轉次數 9 }10 @end11 12 @implementation BKViewController13 14 15 - (void)viewDidLoad {16     [super viewDidLoad];17     // Do any additional setup after loading the view.18     UIBarButtonItem *btnRight = [[UIBarButtonItem alloc] initWithTitle:@"測試" style:UIBarButtonItemStylePlain target:self action:@selector(test)];19     [self.navigationItem setRightBarButtonItem:btnRight];20     21     _isRegistNib = NO;22     _shortDateFormatter = [DateFormatterHelper getShortDateFormatter];23     //資金類型資料載入24     kpType = [NSArray arrayWithObjects:@"記賬日期",@"記賬類型",@"資金流動類型",@"費用科目",nil];25     [self loadTableViewData];26     self.tableview1.dataSource = self;27     self.tableview1.delegate = self;28     29     pushCount = 1;30 }

上面這段代碼主要關注pushCount這個變數,它記錄從A頁面跳往B頁面的次數,初始化為1

 

ok,準備工作完成了,下面說一下要實驗的步驟:

1)從頁面A 跳轉到 頁面B,跳轉之前,將weak的 checkFTWeak 指標指向 頁面B的對象;

2)然後回到頁面A

3)點擊測試按鈕,測試一下 checkFTWeak現在指向的對象是否還存在

4)我們要有一個籠統的概念:strong會持有對象(引用計數+1),weak不會

代碼:

 1 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3     /* 4     LycTableCellViewDefault *cell = (LycTableCellViewDefault *)[tableView cellForRowAtIndexPath:indexPath];*/ 5      6     NSLog(@"當前跳轉次數%i",pushCount); 7     //跳轉到選擇資金類型頁面 8     if (indexPath.section == 0 && indexPath.row == 1) { 9         UIStoryboard *sbMain = [UIStoryboard storyboardWithName:@"Main" bundle:nil];10         CheckFlowTypeViewController *cv = [sbMain instantiateViewControllerWithIdentifier:@"checkFlowTypeSB"];11         12         if (pushCount == 1) {13             self.checkFTWeak = cv;14         }15         NSLog(@"checkFTWeak指向的對象是%@", self.checkFTWeak);16         pushCount++;17         //[self presentViewController:cv animated:YES completion:nil ];18         [self.navigationController pushViewController: cv animated:YES];19     }20 }21 22 -(void)test23 {24     NSLog(@"checkFTWeak指向的對象是%@", self.checkFTWeak);25 }

 

 

首先初始化要跳轉到的頁面B對象 cv,然後將 checkFTWeak 指標指向 cv;接著就列印出對象的資訊

當從B 跳回 到A時,點擊A頁面的測試按鈕,再列印 checkFTWeak指標,看看它指向的對象還存在否

 

通過運行結果,我們看到,當頁面從B 返回 A 之後,checkFTWeak指向的對象,也就是那個頁面b不存在了。

 

那麼如果讓checkFT這個strong類型的屬性指向頁面b是什麼結果呢?

修改tableview選中事件的那句代碼為:self.checkFT = cv;

運行結果為:

可以看到,由於checkFT指標是strong類型的屬性,那麼他會持有頁面B的對象,導致記憶體不會釋放

 

結合上面兩個例子,可以總結下面兩點:

1)頁面跳轉時建立的目標頁面(就是頁面B),在返回後(也就是調用popViewController方法),將會被釋放

2)明白了strong和weak的區別,

strong指向的對象不會被釋放,除非把指標設定為nil;

而weak不會對指向的對象的引用計數有任何影響,在飲用對象不存在時,會返回nil,替我們做了處理;

 

那麼到這裡我還有一個疑問:如果strong類型的指標,本來指向 c,後來又指向d的話,那麼c會被釋放還是繼續存在?

那麼繼續來改造代碼,這個時候前面提到的pushCount參數就起作用了,具體實驗步驟如下:

1)從頁面A跳轉到頁面B,同時讓checkFT、 checkFTWeak 兩種類型的指標指向頁面B的對象

2)返回後列印兩個指標指向的對象

3)再次從頁面A跳轉到頁面B,但是strong類型的 checkFT指標指向新初始化的頁面B,checkFTWeak指標還是指向原來的那個對象

4)返回頁面A,列印兩個指標指向的對象

修改後的代碼:

 1 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 2 { 3     /* 4     LycTableCellViewDefault *cell = (LycTableCellViewDefault *)[tableView cellForRowAtIndexPath:indexPath];*/ 5      6     NSLog(@"當前跳轉次數%i",pushCount); 7     //跳轉到選擇資金類型頁面 8     if (indexPath.section == 0 && indexPath.row == 1) { 9         UIStoryboard *sbMain = [UIStoryboard storyboardWithName:@"Main" bundle:nil];10         CheckFlowTypeViewController *cv = [sbMain instantiateViewControllerWithIdentifier:@"checkFlowTypeSB"];11         self.checkFT = cv;12         13         if (pushCount == 1) {14             self.checkFTWeak = cv;15         }16         NSLog(@"checkFT指向的對象是%@",self.checkFT);17         NSLog(@"checkFTWeak指向的對象是%@", self.checkFTWeak);18         pushCount++;19         //[self presentViewController:cv animated:YES completion:nil ];20         [self.navigationController pushViewController: cv animated:YES];21     }22 }23 24 -(void)test25 {26     NSLog(@"點擊測試按鈕後:");27     NSLog(@"checkFT指向的對象是%@",self.checkFT);28     NSLog(@"checkFTWeak指向的對象是%@", self.checkFTWeak);29 }

啟動並執行結果:

第一次跳轉因為有strong類型的指標checkFT給weak類型的指標checkFTWeak撐腰,所以他倆指向對象一樣。

在返回頁面A後,發生第二次跳轉錢checkFT指向了新的頁面B的對象,checkFTWeak指向的對象被釋放了,所以列印出了nil

那麼又得出了第三個結論:

當strong類型的指標從指向a變成指向b之後,原來的a對象的引用計數將會-1,如果沒有其他指標持有它,它變被arc給釋放了。然後b的引用計數會+1;

分析結束,如果不對之處希望指出共同學習。

 

ios基礎之 透過頁面跳轉來認識 Strong 與 Weak

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.