readwritereadonlyassignretaincopy直接复制,用于基本数据类型(NSInteger/CGFloat), C数据类型(int, float, double, char), 还有 id 类型
不涉及内存管理,当 assign 修饰对象类型是,会导致内存泄漏或 EXC_BAD_ACCESS
虽然 assign 与 weak 的含义接近,但 assign 一般修饰基本数据类型,weak 修饰对象类型,当 weak 修饰对象类型是,当对象被释放后,weak 会将变量自动置 nil, 而 assign 修饰时,变量的对象地址并不会发生变化,但对象却已经被释放了

当对 assign 修饰的对象进行复制时,编译器也会发生警告
针对对象类型进行内存管理,对基本数据类型使用会报错

同时,ARC 下已经不需要使用 retain
主要用于 NSString 类型,用于复制内容,复制行为取决于 - (id)copyWithZone:(NSZone *)zone 的实现
atomicnonatomic线程保护技术,保护变量读取安全,但缺点是浪费系统资源,因此在运行 iOS 的小型设备上,一般使用 nonatomic
而对于需要多线程安全的场景,一般使用 nonatomic 修饰符,并在执行代码中,使用 NSLock 等手动加锁的方法来保证安全
但使用 atomic 之后,所修饰的数据就一定线程安全吗?
不是
线程安全的安全,实际上是指在多线程的情况下,访问同一个数据(内存位置),获得的结果符合预期
而
atomic只能保证属性的getter或setter中线程安全,并不是getter与setter都线程安全 这意味着,当有 A, B 两个线程同时去访问属性 c. A 对 c 进行了写入操作,而后在对 c 进行读取操作,B 也对 c 进行了写操作。而我们预期的结果是:A 对 c 读取的结果应该是 A 对 c 写入的值而此时我们只使用了
atomic来修饰,那么,A 对 c 的写操作是安全的(写入 1),但之后 B 立刻也对 c 进行了写操作(写入 2),实际上这个写操作也是线程安全的。最后 A 才对 c 进行读取,读取到了 2, 而不是我们希望的 1, 此时,就说线程不安全了 而要保证 A 对 c 的写入和读取操作统一,就需要利用额外的锁机制来保证,如NSLock
用于设置自定义 property 的 getter, setter 方法
基本数据类型 atomic + readwrite + assign
Objective-C 对象 atomic + readwrite + strong
@property = ivar + getter + setter
@interface AnObject: NSObject
@property NSString *name;
@end
等价于
@interface AnObject: NSObject
- (NSString *)name;
- (void)setName:(NSString *)name;
@end
@implementation AnObejct
@synthesize name = _name; // _name 为中间变量
- (NSString *)name {
// ...
}
- (void)setName:(NSString *)name {
// ...
}
@end
在 Runtime 中,propery 的定义是
typedef struct objc_property *objc_property_t;
而 objc_property 的定义又是
struct property_t {
const char *name;
const char *attributes;
};
而 attributes 虽然看起来是 char *, 但是它的结构又是
/// Defines a property attribute
typedef struct {
const char *name; // 属性名称
const char *value; // 属性的修饰符,类型
} objc_property_attribute_t;
可以通过 property_getAttributes 获取到 attributes