面试题答案
一键面试区别
- __strong:
- 强引用:__strong修饰的变量是强引用,它会“持有”对象,只要有至少一个__strong变量指向某个对象,该对象就不会被释放。这是Objective-C中默认的变量修饰符。例如,当使用
NSString *str = @"Hello";
时,str
实际上是一个__strong类型的变量,它强引用了字符串对象@"Hello"
。 - 内存管理影响:如果一个对象被多个__strong变量引用,只有当所有指向该对象的__strong变量都不再指向它(比如超出作用域或被赋值为
nil
)时,对象才会被释放。
- 强引用:__strong修饰的变量是强引用,它会“持有”对象,只要有至少一个__strong变量指向某个对象,该对象就不会被释放。这是Objective-C中默认的变量修饰符。例如,当使用
- __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
(强引用)被设置为nil
,Person
对象被释放后,weakPerson
(弱引用)自动被设置为nil
,避免了野指针。