iOS面试题

iOS中属性关键词

2019-09-30  本文已影响0人  太阳和风与旅行者
1. 原子性:nonatomic、atomic
2. 读写:readwrite、readonly
3. 方法名:getter<name>、setter<name>
4. 内存:strong、retain、copy、weak、assign、unsafe_unretain

1.原子性与非原子性

  • atomic:原子性,只有一个线程可以同时访问实例。atomic 是线程安全的(因为会为setter方法加锁),至少在当前的读取器是安全的。虽然它是一个默认属性,但是由于其使用同步锁开销较大,会损耗性能。
  • nonatomic:非原子性的,可以被多个线程访问。效率要比atomic 高,但是不能保证其在多线程状态下的安全性,在单线程和明确只有一个线程访问的情况下被广泛使用。

2.读写属性

  • readwrite(默认值):表示其同时拥有getter 和 setter 方法;
  • readonly:只读操作,其只有getter 方法,没有setter法

注:如果某个实例只允许被外部读取,而不能写入操作,同时在类实现文件当中可以写入的话,可以在头文件中声明属性为只读的,在实现文件中设置其为可读写的属性,写法如下:

//头文件中声明为:
@property(nonatomic,readonly,copy) NSString *stringA;
//实现文件中声明为:
@property(nonatomic,readwrite,copy) NSString *stringA;

3.内存关键词

  • strong表示指向并拥有该对象。其修饰的对象引用计数会增加1。该对象只要引用计数不为0则不会被销毁。当然强行将其设为nil可以销毁它。
  • weak表示指向但不拥有该对象。其修饰的对象引用计数不会增加。无需手动设置,该对象会自行在内存中销毁。
  • assign主要用于修饰基本数据类型,如NSInteger和CGFloat,这些数值主要存在于栈上。
  • weak 一般用来修饰对象,assign一般用来修饰基本数据类型。原因是assign修饰的对象被释放后,指针的地址依然存在,造成野指针,在堆上容易造成崩溃。而栈上的内存系统会自动处理,不会造成野指针。
  • copy与strong类似。不同之处是strong的复制是多个指针指向同一个地址,而copy的复制每次会在内存中拷贝一份对象,指针指向不同地址。copy一般用在修饰有可变对应类型的不可变对象上,如NSString, NSArray, NSDictionary。
  • Objective-C 中,基本数据类型的默认关键字是atomic, readwrite, assign;普通属性的默认关键字是atomic, readwrite, strong。
assign:用于值类型(如int,float等)
weak: 用于修饰引用类型
unsafe_unretained:只修饰引用类型
区别:
1. 三者修饰效果相同,即都不会更改所赋新值的引用计数,也不改变旧值的引用计数
2. assign一般只修饰值类型,虽然也可以修饰引用类型,但是修饰的对象释放后,指针不会自动被置空,此时向对象发消息会崩溃。
3. weak 不会产生野指针问题。因为weak修饰的对象释放后(引用计数器值为0),指针会自动被置nil,之后再向该对象发消息也不会崩溃。 weak是安全的。
4. unsafe_unretained与assign的区别在于,其只修饰引用类型。

strong:用于引用类型,强引用。
retain :用于引用类型,强引用。
copy:修饰属性会在内存里拷贝对象。
区别:
1. 三者都用于修饰引用类型。
2. strong用于ARC,retain用于MRC。
3. copy分为浅层复制和深复制两种,NSString、NSArray、NSDictionary等不可变类型都为浅层复制,即其引用计数会+1,而不会创建新的内存。

浅拷贝:对内存地址的复制,让目标对象指针和原对象指向同一片内存空间会增加引用计数
深拷贝:对对象内容的复制,开辟新的内存空间

可变对象的copy和mutableCopy都是深拷贝
不可变对象的copy是浅拷贝,mutableCopy是深拷贝
copy方法返回的都是不可变对象

@property (nonatomic, copy) NSMutableArray * array;这样写有什么影响?
因为copy方法返回的都是不可变对象,所以array对象实际上是不可变的,如果对其进行可变操作如添加移除对象,则会造成程序crash

上一篇下一篇

猜你喜欢

热点阅读