MST

星途 面试题库

面试题:Objective-C中类的属性修饰符有哪些及各自作用

请详细阐述Objective-C中类的属性修饰符,如nonatomic、atomic、strong、weak、assign、copy等,说明它们在内存管理、线程安全等方面的作用及适用场景。
22.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

nonatomic与atomic

  • 内存管理:对内存管理无直接影响。
  • 线程安全
    • nonatomic:非原子性访问,不保证属性的读写操作是线程安全的。在多线程环境下,可能会出现数据竞争问题。其优势在于性能较高,因为它不涉及线程同步的开销。
    • atomic:原子性访问,保证同一时间只有一个线程能访问该属性,提供了线程安全的读/写操作。它通过在访问器方法中添加锁机制来实现线程安全,但这会带来额外的性能开销。
  • 适用场景
    • nonatomic:适用于性能要求较高,且所在环境线程安全可通过其他方式保证的场景,比如在单线程环境或者已通过其他锁机制保证线程安全的代码块中。
    • atomic:适用于多线程环境下,对数据一致性要求较高,且性能不是首要考虑因素的场景。

strong

  • 内存管理:强引用,持有对象的所有权。当一个对象被一个strong修饰的属性所引用时,该对象的引用计数会增加。只有当所有指向该对象的strong引用都被释放后,对象才会被销毁。
  • 线程安全:本身不提供线程安全,在多线程环境下,若多个线程同时操作strong属性,可能会导致数据竞争和内存管理问题,需要额外的同步机制。
  • 适用场景:通常用于需要保持对象存活,且对象关系为拥有关系的场景。比如视图控制器持有其视图的引用。

weak

  • 内存管理:弱引用,不持有对象的所有权,不会增加对象的引用计数。当对象的所有强引用都被释放后,对象被销毁,所有指向该对象的weak引用会自动被设置为nil,避免了野指针问题。
  • 线程安全:本身不提供线程安全,在多线程环境下可能存在数据竞争问题。
  • 适用场景:适用于解决循环引用问题,比如在视图控制器和其代理之间的关系,代理通常用weak修饰,防止循环引用导致内存泄漏。同时也适用于当你希望对象的生命周期不由自己控制,但又想引用它的场景。

assign

  • 内存管理:简单赋值,不涉及引用计数的操作。主要用于基本数据类型(如int、float等),因为基本数据类型不需要通过引用计数来管理内存。对于对象类型,使用assign修饰属性时,不会增加对象的引用计数,当对象被释放后,指向该对象的指针不会自动置为nil,容易产生野指针。
  • 线程安全:本身不提供线程安全。
  • 适用场景:用于基本数据类型的属性声明。如果非要用于对象类型,仅适用于一些简单场景且能保证对象生命周期长于引用它的对象,否则会有野指针风险。

copy

  • 内存管理:创建一个新的对象副本,并持有该副本的强引用。对于不可变对象(如NSString、NSArray等),copy操作通常返回对象本身(浅拷贝),而对于可变对象,会创建一个新的独立副本(深拷贝)。这有助于确保数据的完整性,防止被其他对象意外修改。
  • 线程安全:本身不提供线程安全。在多线程环境下,如果多个线程同时操作copy属性,也需要额外的同步机制。
  • 适用场景:当你需要确保属性值不会被外部修改时使用。比如,一个视图控制器有一个用于显示文本的NSString属性,为防止外部传入的字符串在其他地方被修改,使用copy修饰该属性。