MST

星途 面试题库

面试题:Objective-C内存管理机制之高级难度:引用计数变化场景

列举至少5种在Objective-C中会导致对象引用计数发生变化的场景,并解释每种场景下引用计数是如何变化的,同时说明这种变化对对象内存释放的影响。
32.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. alloc/new/copy/mutableCopy创建对象
    • 引用计数变化:新创建的对象引用计数为1。例如,使用NSObject *obj = [[NSObject alloc] init];obj的引用计数初始为1。
    • 对内存释放影响:只有当该对象的引用计数减为0时,才会释放其所占用的内存。在此之前,对象一直存在于内存中。
  2. retain方法
    • 引用计数变化:调用retain方法会使对象的引用计数加1。比如[obj retain];obj的引用计数从当前值加1。
    • 对内存释放影响:增加了对象的持有方,只有当所有持有方都释放(引用计数相应减少),使得引用计数变为0时,对象才会被释放。
  3. release方法
    • 引用计数变化:调用release方法会使对象的引用计数减1。如[obj release];obj的引用计数从当前值减1。
    • 对内存释放影响:如果减1后引用计数变为0,对象所占用的内存会被释放,相关资源也会被回收。
  4. autorelease方法
    • 引用计数变化:调用autorelease方法时,对象的引用计数不会立即改变,而是被添加到自动释放池(Autorelease Pool)中。当自动释放池被销毁时,池中的对象会收到release消息,引用计数减1。例如NSObject *obj = [[[NSObject alloc] init] autorelease];,在自动释放池销毁前,obj引用计数不变,自动释放池销毁时,obj引用计数减1。
    • 对内存释放影响:如果自动释放池销毁时,对象引用计数减为0,对象内存被释放。若在自动释放池销毁前对象引用计数已通过其他方式变为0,对象也会提前释放。
  5. 对象作为函数返回值
    • 引用计数变化:当一个对象作为函数返回值返回时,调用者接收该对象,引用计数规则遵循创建对象的规则(如通过alloc创建返回,引用计数为1)。例如:
    - (NSObject *)createObject {
        return [[NSObject alloc] init];
    }
    NSObject *newObj = [self createObject];
    
    这里newObj引用计数为1。
    • 对内存释放影响:调用者负责管理该对象的引用计数,通过releaseautorelease等操作来控制对象的生命周期,当引用计数为0时对象内存被释放。
  6. 属性声明为retain(ARC之前)
    • 引用计数变化:在ARC之前,如果属性声明为retain,当给该属性赋值时,会对新值调用retain方法使其引用计数加1,对旧值调用release方法使其引用计数减1。例如:
    @property (nonatomic, retain) NSObject *myObj;
    - (void)setMyObj:(NSObject *)newObj {
        if (_myObj != newObj) {
            [_myObj release];
            _myObj = [newObj retain];
        }
    }
    
    • 对内存释放影响:正确管理了新旧值的引用计数,确保旧值在不再被使用时能被正确释放,新值被正确持有,避免内存泄漏和悬空指针等问题。当最终对象的引用计数为0时,内存被释放。