在了解@property的属性之前,您应该知道@property的用途。
@property提供了一种定义类所封装信息的方式。如果使用@property声明一个对象/变量,则其他导入该类的类将能够访问该对象/变量。
如果在头文件中使用@property声明一个对象,则必须在实现文件中使用@synthesize合成它。这使得该对象成为KVC兼容的。默认情况下,编译器会为该对象合成访问器方法。
访问器方法包括:setter和getter。
例如: .h
@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.m
@implementation XYZClass
@synthesize name;
@end
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method
@property 的属性列表
atomic, nonatomic, retain, copy, readonly, readwrite, assign, strong, getter=method, setter=method, unsafe_unretained
atomic是默认行为。如果一个对象被声明为原子的,那么它就变成了线程安全的。线程安全意味着,在同一时间内,该类的特定实例只有一个线程可以控制该对象。
如果线程正在执行getter方法,那么其他线程不能在该对象上执行setter方法。这会使程序运行变慢。
@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
因此,访问nonatomic属性比atomic属性更快。
@property (nonatomic)NSString *name;
设置方法将增加对象的保留计数,这样它将占用自动释放池中的内存。
@property (retain)NSString *name;
即使设置了可变字符串并随后更改了它,该实例也会捕获其在设置时具有的任何值。不会合成setter和getter方法。
@property (copy) NSString *name;
现在,
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
name不会受到影响。
编译器将生成getter但不生成setter。
@property (readonly) NSString *name;
它与 readonly 相反。
@property (readwrite) NSString *name;
请记住,在启用垃圾回收时,retain和assign基本上是可以互换的。
@property (assign) NSInteger year;
它随着ARC一起使用。
@property (nonatomic, strong) AVPlayer *player;
对于布尔属性(具有YES或NO值的属性),习惯上getter方法以“is”开头。
@property (getter=isFinished) BOOL finished;
该方法应以冒号结尾。
@property(setter = boolBool:) BOOL finished;
unsafe reference类似于weak reference,因为它不会保留相关对象的存活,但如果目标对象被释放,它不会被设置为nil。
@property (unsafe_unretained) NSObject *unsafeProperty;
@property (readonly, getter=isFinished) BOOL finished;
@property
声明一个对象,那么你在实现文件中就必须使用 @synthesize
来合成它。但并非总是这样。例如,“默认情况下,一个readwrite
属性将由一个实例变量支持,并且该实例变量将由编译器自动合成。”来源于文档。 - Franklin YuMrMage提供的文章链接已不再有效。以下是我在编写Objective-C时学到的一些知识:
nonatomic vs. atomic - "atomic"是默认值。始终使用“nonatomic”。我不知道为什么,但我读过的这本书上说“很少有理由”使用“atomic”。(顺便说一下:我读的是BNR的“iOS编程”书。)
readwrite vs. readonly - "readwrite"是默认值。当您@synthesize时,会为您创建getter和setter。如果您使用“readonly”,则不会创建setter。将其用于您不希望在对象实例化后更改的值。
retain vs. copy vs. assign
@synthesize
,如果未为已声明的属性提供访问器,则现在是默认/隐含的),需要使用nonatomic
标志。例如,如果您希望自定义视图在修改其backgroundColor
属性时标记自身以进行显示,那么您必须声明属性为nonatomic
,然后自己实现-setBackgroundColor:
访问器方法(用于分配新颜色并调用-setNeedsDisplay:
)。否则,最好不指定nonatomic
标志将其默认为原子操作。 - Joshua Nozziatomic
与建议使用 nonatomic
一样糟糕。两种选择都不是“正确”的,因此语言设计者选择了更安全的解决方案。实际上,通常情况下使用nonatomic
是更好的选择,因为它省略了非常昂贵的线程锁。唯一需要使用 atomic
的原因是如果你的属性可能会在多个线程中设置(这种情况下省略它可能会导致过度释放或泄漏)。 - Adam Kaplan阅读了许多文章后,我决定将所有属性信息整合在一起:
- atomic //默认
- nonatomic
- strong=retain //默认
- weak= unsafe_unretained
- retain
- assign //默认
- unsafe_unretained
- copy
- readonly
- readwrite //默认
下面是一个链接,您可以在其中找到这些属性的详细信息。
非常感谢所有在这里提供最佳答案的人!!
以下是文章中的示例说明
示例:
@property (retain) NSString *name;
@synthesize name;
示例:
@property (nonatomic, retain) NSString *name;
@synthesize name;
解释:
假设有一个名为“name”的原子字符串属性,如果您从线程A调用[self setName:“A”],从线程B调用[self setName:“B”],并从线程C调用[self name],则所有不同线程上的操作都将按顺序执行,这意味着如果一个线程正在执行setter或getter,则其他线程将等待。这使属性“name”读/写安全,但如果另一个线程D同时调用[name release],则此操作可能会导致崩溃,因为此处没有涉及setter/getter调用。这意味着对象是读/写安全的(原子性),但不是线程安全的,因为其他线程可以同时向对象发送任何类型的消息。开发人员应确保此类对象的线程安全。
如果属性“name”是非原子的,则上述示例中的所有线程 - A、B、C和D都将同时执行,产生任何不可预测的结果。在原子情况下,A、B或C中的任何一个都将首先执行,但D仍然可以并行执行。
示例:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
weak(iOS4 = unsafe_unretained)
-这意味着“只要有其他人强烈指向它,就将其保留”
-与assign相同,没有retain或release
-“弱”引用是一种不保留的引用。
-我们通常使用weak来处理IBOutlets(UIViewController的子对象)。这是因为子对象只需要在父对象存在时存在。
-弱引用是一种不保护所引用对象免受垃圾回收器回收的引用。
-Weak本质上是一个未保留的属性。除了当对象被释放时,弱指针会自动设置为nil。@property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
强引用和弱引用解释,感谢BJ Homer:
想象一下我们的对象是一只狗,这只狗想要逃跑(被释放)。 强引用就像是狗的绳索。只要你把绳子系在狗身上,狗就不会逃跑。如果五个人把他们的绳子都系在一只狗身上(即一个对象有五个强引用),那么只有当这五个绳子都被解开时,狗才会逃跑。 而弱引用则像是指着狗说“看!一只狗!”的小孩。只要狗还在绳索上,小孩们就能看到狗,并且仍然会指着它。但是,只要所有的绳索都被解开了,无论有多少小孩在指着它,狗都会逃跑。 当最后一个强引用(绳索)不再指向一个对象时,该对象将被释放,所有的弱引用都将被清零。 何时使用弱引用? 唯一需要使用弱引用的时候是为了避免保留环(例如,父对象保留子对象,子对象也保留父对象,因此两者都永远不会被释放)。
@property (nonatomic, retain) NSString *name;
@synthesize name;
示例:
@property (nonatomic, assign) NSString *address;
@synthesize address;
unsafe_unretained
-unsafe_unretained是一个所有权限定符,用于告诉ARC如何插入retain/release调用 -unsafe_unretained是assign的ARC版本。
示例:
@property (nonatomic, unsafe_unretained) NSString *nickName;
@synthesize nickName;
示例:
@property (nonatomic, copy) NSArray *myArray;
@synthesize myArray;
原子属性只能被一个线程同时访问。它是线程安全的。默认是原子的。请注意,没有原子关键字。
非原子意味着多个线程可以访问该项。它是线程不安全的。
因此,在使用原子属性时应非常小心,因为它会影响您代码的性能。
喜欢这些关于iOS中Objective-C属性的链接...
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html