MST

星途 面试题库

面试题:Objective-C中属性的内存管理策略有哪些,如何正确使用?

请详细阐述Objective-C中`assign`、`retain`、`copy`、`strong`、`weak`等属性内存管理策略的特点及适用场景,并举例说明在实际代码中如何正确使用这些策略来避免内存泄漏和悬空指针等问题。
16.8万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

assign

  • 特点:简单赋值,不改变引用计数。适用于基本数据类型(如 intfloatchar 等),对于对象类型,当对象释放后,指针不会自动置为 nil,可能产生悬空指针。
  • 适用场景:基本数据类型的属性声明。
  • 示例
@property (nonatomic, assign) int age;

retain

  • 特点:对对象进行引用计数加1操作。当对象的引用计数变为0时,对象被释放。
  • 适用场景:在MRC(手动引用计数)时代,用于对需要保持所有权的对象进行属性声明。
  • 示例
@property (nonatomic, retain) NSString *name;

copy

  • 特点:创建一个新的对象副本,新对象的引用计数为1。对于不可变对象,通常返回自身(浅拷贝);对于可变对象,返回一个新的对象(深拷贝)。
  • 适用场景:当需要确保属性值不被外部修改时,如 NSStringNSArrayNSDictionary 等。防止外部传入可变对象后,对象内容被修改影响到本类数据。
  • 示例
@property (nonatomic, copy) NSString *text;

strong

  • 特点:ARC(自动引用计数)下的强引用,等同于MRC中的 retain,会增加对象的引用计数。当强引用指向的对象没有其他强引用时,对象会被释放。
  • 适用场景:一般情况下,需要持有对象所有权时使用。
  • 示例
@property (nonatomic, strong) NSObject *object;

weak

  • 特点:弱引用,不会增加对象的引用计数。当对象被释放时,指向该对象的所有弱引用会自动被设置为 nil,避免悬空指针。
  • 适用场景:用于解决循环引用问题,如视图控制器之间的父子关系,或者避免持有对象而导致对象无法释放。
  • 示例
@property (nonatomic, weak) UIViewController *parentViewController;

避免内存泄漏和悬空指针

  1. 内存泄漏:在ARC下,避免循环引用可解决大部分内存泄漏问题。例如在两个对象相互强引用时,可将其中一个改为弱引用。
@interface ClassA;
@interface ClassB {
    @property (nonatomic, strong) ClassA *a;
}
@end

@interface ClassA {
    @property (nonatomic, weak) ClassB *b; // 使用weak避免循环引用
}
@end
  1. 悬空指针:使用 weak 修饰符,当对象释放时,指向该对象的 weak 指针会自动置为 nil,防止访问已释放对象导致的悬空指针问题。
__weak NSObject *weakObject;
{
    NSObject *strongObject = [[NSObject alloc] init];
    weakObject = strongObject;
} // strongObject出作用域被释放,weakObject自动置为nil