首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 內存管理面試題深度解析:autorelease 池與指針陷阱

     編輯:關於C語言

Objective-C 內存管理面試題深度解析:autorelease 池與指針陷阱

iOS 應用崩潰超 90% 由內存問題引起。在龐大工程中排查極難,掌握常見陷阱可顯著降低出錯率。內存問題主要表現為:內存洩漏、野指針、過度釋放。本文解析兩道經典面試題,揭示 autorelease 機制與指針重賦值的隱患。

面試題一:大循環中的 autorelease 導致內存洩漏

@autoreleasepool {
    for (long i = 0; i < largeNumber; i++) {
        Person *per = [[Person alloc] init];
        [per autorelease];
    }
}

問題分析

表面上 alloc 與 autorelease 配對,符合內存管理原則。但 autorelease 並非立即釋放,而是將對象放入最近的自動釋放池,池銷毀時才發送 release。若 largeNumber 極大,循環期間對象堆積在池中,導致內存飆升甚至 OOM。

解決方案:內層建立自動釋放池

@autoreleasepool {
    for (long i = 0; i < largeNumber; i++) {
        @autoreleasepool {
            Person *per = [[Person alloc] init];
            [per autorelease];
        } // 每次迭代結束,內層池銷毀,對象及時釋放
    }
}

關鍵點:在循環內部創建新的 @autoreleasepool,確保每次迭代結束時釋放當前對象,避免內存累積。

面試題二:指針重賦值導致原對象洩漏與常量區釋放崩潰

@autoreleasepool {
    NSString *per = [[NSString alloc] init];
    [per retain];
    [per retain];
    per = @"aa";
    [per release];
    [per release];
    [per release];
}

問題分析

  1. 內存洩漏:per = @"aa" 使指針指向常量區字面量,原 alloc 的堆對象失去引用,無法釋放,造成洩漏。
  2. 錯誤釋放常量區:後續三次 release 作用於常量區對象,常量區無需手動管理,會導致崩潰或未定義行為。
  3. 引用計數失衡:原對象 retain 2 次(計數 3),但釋放操作全給了新對象。

正確做法

若需重新賦值,應先釋放原對象:

[per release]; // 釋放原 alloc 對象
[per release]; // 對應兩次 retain
per = @"aa";   // 指向常量區,無需 release

核心原則總結

  • autorelease 延遲釋放:大循環必須用內層池控制作用域
  • 指針重賦值前必須釋放舊對象:否則洩漏
  • 常量區對象(字面量)不可 release:由系統管理
  • 嚴格遵循 alloc/copy/retain 與 release/autorelease 配對

理解運行時機制,而非死記規則,才能寫出健壯的 Objective-C 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved