ARC 環(huán)境下,下面代碼中的局部變量是何時(shí)被銷毀的?

- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *arr = [NSArray arrayWithObject:@"sun"];
}

前言

前天挖了一個(gè)坑,今天先把它填上。
本文適合簡單快速的回答面試官的問題。對于更深的相關(guān)知識,請關(guān)注后續(xù)的文章或者自行查閱相關(guān)資料。

簡單版答案

在 ARC 下,+arrayWithObject: 方法會(huì)自動(dòng)調(diào)用 -autorelease 方法。
調(diào)用后,該變量會(huì)被添加到自動(dòng)釋放池。
在主線程中,臨時(shí)變量會(huì)在 runloop 運(yùn)行結(jié)束時(shí)釋放。
在非主線程中,臨時(shí)變量會(huì)在 線程退出時(shí)釋放。
所以,當(dāng)有大量的臨時(shí)對象時(shí),官方建議我們使用 @autoreleasepool 進(jìn)行內(nèi)存管理。

NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
 
    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}

測試

為了測試,本文創(chuàng)建了一個(gè)類,SunObject 并實(shí)現(xiàn)了 -dealloc方法。

測試代碼

@interface SunObject : NSObject

@end

@implementation SunObject

- (void)dealloc {
}

@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    __unused NSMutableArray *arr = [NSMutableArray arrayWithObject:[SunObject new]];
}

Allocations

通過 Allocations 工具,我們可以查看變量的生命周期。如下圖所示。

Paste_Image.png

下面是手動(dòng)打印的調(diào)用棧??梢悦黠@發(fā)現(xiàn) 釋放操作是在 libobjc.A.dylib(anonymous namespace)::AutoreleasePoolPage::pop(void*)`的后面。

(lldb) bt
* thread #1: tid = 0x44ecce, 0x0000000105118597 內(nèi)存管理`-[SunObject dealloc](self=0x00007fbbb0e09650, _cmd="dealloc") + 23 at ViewController.m:22, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000105118597 內(nèi)存管理`-[SunObject dealloc](self=0x00007fbbb0e09650, _cmd="dealloc") + 23 at ViewController.m:22
    frame #1: 0x000000010562eafe libobjc.A.dylib`objc_object::sidetable_release(bool) + 232
    frame #2: 0x0000000105a8498d CoreFoundation`-[__NSArrayM dealloc] + 157
    frame #3: 0x000000010562eafe libobjc.A.dylib`objc_object::sidetable_release(bool) + 232
    frame #4: 0x000000010562f0b8 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 488
    frame #5: 0x00000001089c58d0 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 32
    frame #6: 0x00000001089c5741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178
    frame #7: 0x00000001089c5aca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #8: 0x0000000105acc301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #9: 0x0000000105ac222c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #10: 0x0000000105ac16e3 CoreFoundation`__CFRunLoopRun + 867
    frame #11: 0x0000000105ac10f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #12: 0x0000000105f57f21 UIKit`-[UIApplication _run] + 402
    frame #13: 0x0000000105f5cf09 UIKit`UIApplicationMain + 171
    frame #14: 0x0000000105118b9f 內(nèi)存管理`main(argc=1, argv=0x00007fff5aae76a0) + 111 at main.m:14
    frame #15: 0x000000010838092d libdyld.dylib`start + 1
(lldb) 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,740評論 18 399
  • Object-c的類可以多重繼承么?可以實(shí)現(xiàn)多個(gè)接口么?Category是什么?重寫一個(gè)類的方式用繼承好還是分類好...
    small_Sun閱讀 780評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,616評論 19 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,150評論 25 708
  • 一個(gè)很小的屋子里,昏暗的燈光下,有一個(gè)白衣女人呵呵笑著,手里還拿著一把在滴血的水果刀,而一個(gè)男孩癱坐在地上,身上都...
    宄遇三閱讀 198評論 0 0

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