Objective-C和Swift中实例变量属性(关键字)

strong(默认属性)

强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。
弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。

weak

  • 修饰Object类型,修饰的对象在释放后,指针地址会被置为nil,是一种弱引用。在ARC环境下,为避免循环引用,往往会把delegate属性用weak修饰;在MRC下使用assign修饰。weak和strong不同的是:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使还有weak型指针指向它,那么这些weak型指针也将被清除。
  • weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。

atomic(默认属性)

  • 当一个变量声明为atomic时,意味着在多线程中只能有一个线程能对它进行访问

  • 当一个变量声明为atomic时,该变量为线程安全型,但是会影响访问速度,

  • 当一个变量声明为atomic时,在非ARC编译环境下,需要设置访问锁来保证对该变量进行正确的get/set

nonatomic

  • 当一个变量声明为nonatomic时,意味着多个线程可以同时对其进行访问

  • 当一个变量声明为nonatomic时,它是非线程安全型,访问速度快;

  • 当一个变量声明为nonatomic时,当两个不同的线程对其访问时,容易失控。

assign

用于对基本数据类型进行赋值操作,不更改引用计数。也可以用来修饰对象,但是,被assign修饰的对象在释放后,指针的地址还是存在的,也就是说指针并没有被置为nil,成为野指针。如果后续在分配对象到堆上的某块内存时,正好分到这块地址,程序就会crash。之所以可以修饰基本数据类型,因为基本数据类型一般分配在栈上,栈的内存会由系统自动处理,不会造成野指针。

copy

会在内存里拷贝一份对象,两个指针指向不同的内存地址。一般用来修饰NSString等有对应可变类型的对象,因为他们有可能和对应的可变类型(NSMutableString)之间进行赋值操作,为确保对象中的字符串不被修改 ,应该在设置属性是拷贝一份。而若用strong修饰,如果对象在外部被修改了,会影响到属性。

注意:

1.readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。

2.默认的property行为有:atomic,assign,readwrite。


以下摘自Swift学习: 从Objective-C到Swift

strong: 在Swift中是默认的

weak: 通过weak关键词申明

weak var delegate: UITextFieldDelegate? 

readonly,readwrite:Swift没有这两个attribute,如果是定义一个stored property,通过let定义它只读,通过var定义它可读可写。如果想实现类似Objective-C中,对外在头文件.h 声明property为readonly,对内在.m声明property为readwrite
,这种情况在Swift通过Access Control来实现:

private(set) var property: Int

copy:通过@NSCopying指令声明。
值得注意的是String,Array和Dictionary在Swift是以值类型(value type)而不是引用类型(reference type)出现,因此它们在赋值,初始化,参数传递中都是以拷贝的方式进行(简单来说,String,Array,Dictionary在Swift中是通过struct实现的)

nonatomic,atomic:所有的Swift properties 都是nonatomic。但是我们在线程安全上已经有许多机制,例如NSLock,GCD相关API等。个人推测原因是苹果想把这一个本来就用的很少的特性去掉,线程安全方面交给平时我们用的更多的机制去处理。


欢迎补充

你可能感兴趣的:(Objective-C和Swift中实例变量属性(关键字))