MST

星途 面试题库

面试题:Objective-C中__weak与__strong变量修饰符语义基础

请简要描述Objective-C中__weak和__strong变量修饰符在内存管理方面的主要区别,并举例说明在ARC环境下,使用__weak修饰的变量在对象释放时会有怎样的表现。
14.4万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

区别

  1. __strong
    • 强引用:__strong修饰的变量是强引用,它会“持有”对象,只要有至少一个__strong变量指向某个对象,该对象就不会被释放。这是Objective-C中默认的变量修饰符。例如,当使用NSString *str = @"Hello";时,str实际上是一个__strong类型的变量,它强引用了字符串对象@"Hello"
    • 内存管理影响:如果一个对象被多个__strong变量引用,只有当所有指向该对象的__strong变量都不再指向它(比如超出作用域或被赋值为nil)时,对象才会被释放。
  2. __weak
    • 弱引用:__weak修饰的变量是弱引用,它不会“持有”对象,不会增加对象的引用计数。即使有__weak变量指向对象,当对象的强引用计数降为0时,对象依然会被释放。
    • 内存管理影响:当对象被释放时,所有指向该对象的__weak变量会自动被设置为nil,从而避免了野指针的产生。这对于解决循环引用问题非常有用,比如在视图控制器之间的父子关系中,父视图控制器持有子视图控制器(强引用),子视图控制器若使用__weak引用父视图控制器,就可以避免循环引用导致的内存泄漏。

举例说明__weak修饰变量在对象释放时的表现

在ARC环境下,示例代码如下:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end

@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.name = @"John";
        __weak Person *weakPerson = person;
        
        NSLog(@"Before releasing: weakPerson = %@", weakPerson);
        person = nil; // 强引用变量置为nil,Person对象的引用计数降为0,对象被释放
        
        NSLog(@"After releasing: weakPerson = %@", weakPerson);
    }
    return 0;
}

输出结果为:

Before releasing: weakPerson = <Person: 0x10060b140>
After releasing: weakPerson = (null)

可以看到,当person(强引用)被设置为nilPerson对象被释放后,weakPerson(弱引用)自动被设置为nil,避免了野指针。