从一个弱引用导致的奔溃 谈 weak assign strong的应用场景【iOS开发教程】

时间:2023-03-08 22:16:57

从一个弱引用导致的奔溃 谈 weak assign strong的应用场景

.h中的定义方法一:

 @property (nonatomic, assign) NSArray *dataSource;

定义方法二

 @property (nonatomic, strong) NSArray *dataSource;

.m中的实现方法

- (void)viewDidLoad {
[super viewDidLoad];
if (YES) {
NSArray *array = @[@"1", @"2", @"3"];
self.dataSource = array;
}
if (self.dataSource.count > 2) {
NSLog(@"self.dataSource 是否能打印?能打印说明可以定义为assign");
}
}

结果。h中方法⓵崩溃了,方法⓶可以执行,

但是如果还是用方法⓵该如何,解决呢?

- (void)viewDidLoad {
[super viewDidLoad];
if (YES) {
NSArray *array = @[@"1", @"2", @"3"];
self.dataSource = [array copy];
}
if (self.dataSource.count > 2) {
NSLog(@"self.dataSource 是否能打印?能打印说明可以定义为assign");
}
}

或者

- (void)viewDidLoad {
[super viewDidLoad];
if (YES) {
NSArray *array = @[@"1", @"2", @"3"];
self.dataSource = [NSArray arrayWithArray:array];
}
if (self.dataSource.count > 2) {
NSLog(@"self.dataSource 是否能打印?能打印说明可以定义为assign");
}
}

总之,这两种改进方案,和strong一个道理,strong是在setter中,就对等号右边的值进行了strong操作,
那为什么把上面的self.dataSource改成_dataSource同样不会引起崩溃呢?
_dataSource
编译器自动生成了setter方法,并生成了_dataSource 这个iVar变量,指向的是同一块儿内存区域。

同时也可以看出,strong也影响到了_dataSource的赋值。看下MRC会更直观:

ARC的setter

// _age的setter和getter
- (void)setAge:(int)age
{
_age = age;
}

MRC的setter

//@property (nonatomic, retain) NSString *name;
- (void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name retain];
}
}
//@property(nonatomic, copy) NSString *name;
- (void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name copy];
}
}