本人参考GitHub《招聘一个靠谱的iOS》面试题参考答案(上)
11. @synthesize和@dynamic分别有什么作用?
12. ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?
13. 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
14. 对非集合类对象的copy操作
15. 集合类对象的copy与mutableCopy
11. @synthesize和@dynamic分别有什么作用?
- @property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@synthesize var = _var;
- @synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
- @dynamic告诉编译器:属性的setter和getter方法由用户自己实现,不自动生成。(对于readonly的属性只需提供getter即可)假如一个属性被声明为@dynamic var,又没有手动实现setter方法和getter方法,编译的时候没有问题,但当程序运行到instance.var = someVar时,由于缺少setter方法会导致程序崩溃,或者运行到someVar = instance.var时,由于缺getter方法同样会导致崩溃。编译的时候没有问题,运行时才执行相应的方法,这就是所谓的动态绑定。
12. ARC下,不显示指定任何属性关键字时,默认的关键字有哪些?
- 对应基本类型默认关键字是atomic, readwrite, assign
2.对应普通的Objective-C对象atomic,readwrite,strong
13. 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
- 因为父类指针可以指向子类对象,使用copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入的是一个可变对象还是不可变对象,我本身持有的就是一个不可变的副本;
- 如果我们使用strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。
举例说明:
定义一个以strong修饰的array:
@property (nonatomic, readwrite, strong) NSArray *array;
NSArray *array = @[@1, @2, @3, @4];
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
self.array = mutableArray;
[mutableArray removeAllObjects];
NSLog(@"%@", self.array);
打印结果:
2018-10-28 19:10:32.523 arrayCopyDemo[10681:713670] (
)
NSArray *array = @[@1, @2, @3, @4];
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
self.array = [mutableArray copy];
[mutableArray removeAllObjects];
NSLog(@"%@", self.array);
打印结果:
2018-10-28 19:10:32.523 arrayCopyDemo[10681:713670] (
1,
2,
3,
4
)
从以上的两个demo可以看出,当不使用copy时,可变子类赋值给不可变父类时,对子类的操作会影响父类的结果。使用copy时,父类得到的是一个不可变的副本,无论可变子类如何变化,不影响不可变父类。
copy的复制又分为对非集合类对象的复制和对集合类对象的复制两种情况。
14. 对非集合类对象的copy操作:
在非集合类对象中,对immutable对象进行copy操作,是指针复制(浅复制),mutableCopy是内容复制(深复制);对mutable对象进行copy和mutableCopy都是内容复制(深复制)。
- [immutableObject copy] // 浅复制
- [immutableObject mutableCopy] // 深复制
- [mutableObject copy] // 深复制
- [mutableObject mutableCopy] // 深复制
15. 集合类对象的copy与mutableCopy
集合对象是指NSArray、NSDictionary、NSSet之类的对象。
immutable对象使用copy和mutableCopy的例子:
NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"]];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
查看内存,copyArray和array的地址是一样的,mutableCopyArray和array的地址是不同的。说明copy进行了指针拷贝(浅拷贝),mutableCopy进行了内容拷贝(深拷贝)。此处的内容拷贝(深拷贝),仅仅拷贝array这个对象,array集合内的元素仍然是指针拷贝(浅拷贝)。
mutable对象使用copy和mutableCopy的例子:
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"], @"b", @"c", nil];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
查看内存,copyArray、mutableCopyArray和array的内存地址都不一样,说明copyArray、mutableCopyArray都对array进行了内容拷贝。
综上所述,在集合类对象中,对immutable对象进行copy,是指针复制(浅复制),mutableCopy是内容复制(深复制),对mutable对象进行copy和mutableCopy都是内容复制(深复制)。但是,集合对象的深复制,仅限于对象本身,对象元素仍然是指针复制。
- [immutableObject copy] // 浅复制
- [immutableObject mutableCopy] // 单层深复制
- [mutableObject copy] // 单层深复制
- [mutableObject mutableCopy] // 单层深复制