MST

星途 面试题库

面试题:Objective-C中ARC在复杂数据结构下的内存管理行为

假设你有一个复杂的数据结构,例如由多个自定义类相互嵌套组成的树状结构,每个节点类都包含对其他节点的强引用。在ARC环境下,如何确保内存管理的正确性,避免循环引用问题?请详细描述实现思路并给出关键代码示例。
49.4万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 使用弱引用:在可能产生循环引用的地方,将强引用改为弱引用。弱引用不会增加对象的引用计数,当对象的强引用计数变为0时,对象会被释放,此时弱引用会自动被设置为nil
  2. 合理设计数据结构:分析数据结构中可能出现循环引用的路径,从设计层面尽量避免形成循环。例如,对于树状结构,通常父节点持有子节点的强引用,而子节点对父节点使用弱引用。

关键代码示例

假设我们有一个简单的树状结构,包含TreeNode类,每个节点有一个父节点和多个子节点:

class TreeNode {
    var value: Int
    var children = [TreeNode]()
    // 使用弱引用避免循环引用
    weak var parent: TreeNode?

    init(value: Int) {
        self.value = value
    }

    func addChild(_ child: TreeNode) {
        children.append(child)
        child.parent = self
    }
}

在上述代码中,parent属性被声明为weak,这样就避免了父子节点之间可能产生的循环引用。

如果是在Objective - C中:

#import <Foundation/Foundation.h>

@interface TreeNode : NSObject

@property (nonatomic, assign) NSInteger value;
@property (nonatomic, strong) NSMutableArray<TreeNode *> *children;
// 使用弱引用避免循环引用
@property (nonatomic, weak) TreeNode *parent;

- (instancetype)initWithValue:(NSInteger)value;
- (void)addChild:(TreeNode *)child;

@end

@implementation TreeNode

- (instancetype)initWithValue:(NSInteger)value {
    self = [super init];
    if (self) {
        _value = value;
        _children = [NSMutableArray array];
    }
    return self;
}

- (void)addChild:(TreeNode *)child {
    [self.children addObject:child];
    child.parent = self;
}

@end

在Objective - C中,通过weak关键字来声明parent属性,以防止循环引用。