ios @property 在 Objective-C 中保留、分配、复制、非原子性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2255861/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@property retain, assign, copy, nonatomic in Objective-C
提问by Mark Reid
As someone that's new to Objective-C can someone give me an overview of the retain, assign, copy and any others I'm missing, that follow the @property directive? What are they doing and why would I want to use one over another?
作为Objective-C的新手,有人可以给我一个关于保留、分配、复制以及我遗漏的任何其他内容的概述,遵循@property指令吗?他们在做什么,为什么我要使用一个而不是另一个?
回答by liza
Before you know about the attributes of @property, you should know what is the use of @property.
在了解@property 的属性之前,您应该知道@property 的用途是什么。
@propertyoffers a way to define the information that a class is intended to encapsulate. If you declare an object/variable using @property, then that object/variable will be accessible to other classes importing its class.
If you declare an object using @propertyin the header file, then you have to synthesize it using @synthesizein the implementation file. This makes the object KVC compliant. By default, compiler will synthesize accessor methodsfor this object.
accessor methods are : setter and getter.
@property提供了一种定义类要封装的信息的方法。如果您使用@property声明一个对象/变量,那么导入其类的其他类将可以访问该对象/变量。
如果你在头文件中使用@property声明一个对象,那么你必须在实现文件中使用@synthesize来合成它。这使得对象KVC 兼容。默认情况下,编译器会为此对象合成访问器方法。
访问器方法是:setter 和 getter。
Example: .h
示例:.h
@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.m
.m
@implementation XYZClass
@synthesize name;
@end
Now the compiler will synthesize accessor methods for name.
现在编译器将为name合成访问器方法。
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method
List of attributes of @property
atomic, nonatomic, retain, copy, readonly, readwrite, assign, strong, getter=method, setter=method, unsafe_unretained
atomicis the default behavior. If an object is declared as atomic then it becomes thread-safe. Thread-safe means, at a time only one thread of a particular instance of that class can have the control over that object.
@property的属性列表
原子、非原子、保留、复制、只读、读写、分配、强、getter=method、setter=method、unsafe_unretained
atomic是默认行为。如果一个对象被声明为原子的,那么它就成为线程安全的。线程安全意味着,一次只有该类特定实例的一个线程可以控制该对象。
If the thread is performing getter method then other thread cannot perform setter method on that object. It is slow.
如果线程正在执行 getter 方法,则其他线程无法对该对象执行 setter 方法。它很慢。
@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
- nonatomicis not thread-safe. You can use the nonatomic property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads.
- nonatomic不是线程安全的。您可以使用 nonatomic 属性属性来指定合成访问器只是直接设置或返回一个值,不保证如果从不同线程同时访问相同值会发生什么。
For this reason, it's faster to access a nonatomic property than an atomic one.
出于这个原因,访问非原子属性比访问原子属性更快。
@property (nonatomic)NSString *name;
- retainis required when the attribute is a pointer to an object.
- 当属性是指向对象的指针时需要保留。
The setter method will increase retain count of the object, so that it will occupy memory in autorelease pool.
setter 方法会增加对象的保留计数,使其在自动释放池中占用内存。
@property (retain)NSString *name;
- copyIf you use copy, you can't use retain. Using copy instance of the class will contain its own copy.
- 复制如果使用复制,则不能使用保留。使用类的副本实例将包含它自己的副本。
Even if a mutable string is set and subsequently changed, the instance captures whatever value it has at the time it is set. No setter and getter methods will be synthesized.
即使设置了可变字符串并随后更改,该实例也会捕获它在设置时的任何值。不会合成 setter 和 getter 方法。
@property (copy) NSString *name;
now,
现在,
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
namewill remain unaffected.
名称将不受影响。
- readonlyIf you don't want to allow the property to be changed via setter method, you can declare the property readonly.
- readonly如果不想让属性通过 setter 方法改变,可以将属性声明为 readonly。
Compiler will generate a getter, but not a setter.
编译器将生成一个 getter,但不会生成一个 setter。
@property (readonly) NSString *name;
- readwriteis the default behavior. You don't need to specify readwrite attribute explicitly.
- 读写是默认行为。您不需要显式指定 readwrite 属性。
It is opposite of readonly.
它与只读相反。
@property (readwrite) NSString *name;
- assignwill generate a setter which assigns the value to the instance variable directly, rather than copying or retaining it. This is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.
- assign将生成一个 setter,它将值直接分配给实例变量,而不是复制或保留它。这最适用于 NSInteger 和 CGFloat 等原始类型,或您不直接拥有的对象,例如委托。
Keep in mind retain and assign are basically interchangeable when garbage collection is enabled.
请记住,启用垃圾收集时,保留和分配基本上可以互换。
@property (assign) NSInteger year;
- strongis a replacement for retain.
- strong是保留的替代品。
It comes with ARC.
它带有ARC。
@property (nonatomic, strong) AVPlayer *player;
- getter=methodIf you want to use a different name for a getter method, it's possible to specify a custom name by adding attributes to the property.
- getter=method如果要为 getter 方法使用不同的名称,可以通过向属性添加属性来指定自定义名称。
In the case of Boolean properties (properties that have a YES or NO value), it's customary for the getter method to start with the word “is”
对于布尔属性(具有 YES 或 NO 值的属性),getter 方法通常以单词“is”开头
@property (getter=isFinished) BOOL finished;
- setter=methodIf you want to use a different name for a setter method, it's possible to specify a custom name by adding attributes to the property.
- setter=method如果要为 setter 方法使用不同的名称,可以通过向属性添加属性来指定自定义名称。
The method should end with a colon.
该方法应以冒号结尾。
@property(setter = boolBool:) BOOL finished;
- unsafe_unretainedThere are a few classes in Cocoa and Cocoa Touch that don't yet support weak references, which means you can't declare a weak property or weak local variable to keep track of them. These classes include NSTextView, NSFont and NSColorSpace,etc. If you need to use a weak reference to one of these classes, you must use an unsafe reference.
- unsafe_unretainedCocoa 和 Cocoa Touch 中有一些类尚不支持弱引用,这意味着您无法声明弱属性或弱局部变量来跟踪它们。这些类包括 NSTextView、NSFont 和 NSColorSpace 等。如果需要对这些类之一使用弱引用,则必须使用不安全的引用。
An unsafe reference is similar to a weak reference in that it doesn't keep its related object alive, but it won't be set to nilif the destination object is deallocated.
不安全引用类似于弱引用,因为它不会保持其相关对象的活动状态,但如果目标对象被释放,则不会将其设置为nil。
@property (unsafe_unretained) NSObject *unsafeProperty;
If you need to specify multiple attributes, simply include them as a comma-separated list, like this:
如果您需要指定多个属性,只需将它们作为逗号分隔的列表包含,如下所示:
@property (readonly, getter=isFinished) BOOL finished;
回答by Blamdarot
The article linked to by MrMage is no longer working. So, here is what I've learned in my (very) short time coding in Objective-C:
MrMage 链接的文章不再有效。所以,这是我在 Objective-C 中(非常)短时间编码中学到的东西:
nonatomic vs. atomic - "atomic" is the default. Always use "nonatomic". I don't know why, but the book I read said there is "rarely a reason" to use "atomic". (BTW: The book I read is the BNR "iOS Programming" book.)
非原子与原子 - “原子”是默认值。始终使用“非原子”。我不知道为什么,但我读过的书说“很少有理由”使用“原子”。(顺便说一句:我读的书是 BNR“iOS 编程”书。)
readwrite vs. readonly - "readwrite" is the default. When you @synthesize, both a getter and a setter will be created for you. If you use "readonly", no setter will be created. Use it for a value you don't want to ever change after the instantiation of the object.
readwrite 与 readonly - “readwrite”是默认值。当您@synthesize 时,将为您创建一个 getter 和一个 setter。如果您使用“只读”,则不会创建任何 setter。将它用于您不想在对象实例化后更改的值。
retain vs. copy vs. assign
保留与复制与分配
- "assign" is the default. In the setter that is created by @synthesize, the value will simply be assigned to the attribute. My understanding is that "assign" should be used for non-pointer attributes.
- "retain" is needed when the attribute is a pointer to an object. The setter generated by @synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.
- "copy" is needed when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
- “分配”是默认值。在由@synthesize 创建的 setter 中,值将简单地分配给属性。我的理解是“assign”应该用于非指针属性。
- 当属性是指向对象的指针时,需要“保留”。@synthesize 生成的 setter 将保留(也就是添加保留计数)对象。完成后,您需要释放该对象。
- 当对象可变时需要“复制”。如果您需要当前对象的值,并且您不希望该值反映该对象的其他所有者所做的任何更改,请使用此选项。完成后您需要释放对象,因为您保留了副本。
回答by swiftBoy
After reading many articles I decided to put all the attributes information together:
看了很多文章我决定把所有的属性信息放在一起:
- atomic //default
- nonatomic
- strong=retain //default
- weak= unsafe_unretained
- retain
- assign //default
- unsafe_unretained
- copy
- readonly
- readwrite //default
- 原子 //默认
- 非原子的
- 强=保留//默认
- 弱 = unsafe_unretained
- 保持
- 赋值 //默认
- unsafe_unretained
- 复制
- 只读
- 读写 //默认
Below is a link to the detailed article where you can find these attributes.
下面是详细文章的链接,您可以在其中找到这些属性。
Many thanks to all the people who give best answers here!!
非常感谢所有在这里给出最佳答案的人!!
Here is the Sample Description from Article
这是文章中的示例描述
- atomic-Atomic means only one thread access the variable(static type). -Atomic is thread safe. -but it is slow in performance -atomic is default behavior -Atomic accessors in a non garbage collected environment (i.e. when using retain/release/autorelease) will use a lock to ensure that another thread doesn't interfere with the correct setting/getting of the value. -it is not actually a keyword.
- atomic-Atomic 表示只有一个线程访问变量(静态类型)。-Atomic 是线程安全的。- 但它的性能很慢 - 原子是默认行为 - 非垃圾收集环境中的原子访问器(即使用保留/释放/自动释放时)将使用锁来确保另一个线程不会干扰正确的设置/获取的价值。-它实际上不是关键字。
Example :
例子 :
@property (retain) NSString *name;
@synthesize name;
- nonatomic-Nonatomic means multiple thread access the variable(dynamic type). -Nonatomic is thread unsafe. -but it is fast in performance -Nonatomic is NOT default behavior,we need to add nonatomic keyword in property attribute. -it may result in unexpected behavior, when two different process (threads) access the same variable at the same time.
- 非原子-Nonatomic装置多线程访问的变量(动态型)。-Nonatomic 是线程不安全的。- 但它的性能很快 - Nonatomic 不是默认行为,我们需要在 property 属性中添加 nonatomic 关键字。- 当两个不同的进程(线程)同时访问同一个变量时,它可能会导致意外行为。
Example:
例子:
@property (nonatomic, retain) NSString *name;
@synthesize name;
Explain:
解释:
Suppose there is an atomic string property called "name", and if you call [self setName:@"A"] from thread A, call [self setName:@"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait. This makes property "name" read/write safe but if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here. Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object. Developer should ensure thread safety for such objects.
假设有一个原子字符串属性叫做“name”,如果你从线程A调用[self setName:@"A"],从线程B调用[self setName:@"B"],然后从线程调用[self setName:@"B"]线程C,那么对不同线程的所有操作将串行执行,这意味着如果一个线程正在执行setter或getter,则其他线程将等待。这使得属性“name”读/写安全,但如果另一个线程 D 同时调用 [name release] ,则此操作可能会导致崩溃,因为此处不涉及 setter/getter 调用。这意味着一个对象是读/写安全 (ATOMIC) 但不是线程安全的,因为另一个线程可以同时向该对象发送任何类型的消息。开发人员应确保此类对象的线程安全。
If the property "name" was nonatomic, then all threads in above example - A,B, C and D will execute simultaneously producing any unpredictable result. In case of atomic, Either one of A, B or C will execute first but D can still execute in parallel.
如果属性“name”是非原子的,那么上例中的所有线程——A、B、C 和 D 将同时执行,产生任何不可预测的结果。在原子的情况下,A、B 或 C 中的任何一个将首先执行,但 D 仍然可以并行执行。
- strong(iOS4 = retain ) -it says "keep this in the heap until I don't point to it anymore" -in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain" -You use strong only if you need to retain the object. -By default all instance variables and local variables are strong pointers. -We generally use strong for UIViewControllers (UI item's parents) -strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.
- 强(iOS4 = 保留)-它说“将其保留在堆中,直到我不再指向它为止”-换句话说,“我是所有者,您无法在与保留相同的目标之前解除分配”-只有在需要保留对象时才使用 strong。- 默认情况下,所有实例变量和局部变量都是强指针。-我们通常使用强于UIViewControllers(UI项的父母)-strong使用与ARC,它基本上可以帮助你,因为不必担心保留对象的数量。当您完成它时,ARC 会自动为您释放它。使用关键字 strong 表示您拥有该对象。
Example:
例子:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
- weak(iOS4 = unsafe_unretained ) -it says "keep this as long as someone else points to it strongly" -the same thing as assign, no retain or release -A "weak" reference is a reference that you do not retain. -We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only needs to exist as long as the parent object does. -a weak reference is a reference that does not protect the referenced object from collection by a garbage collector. -Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil
- 弱(iOS4 = unsafe_unretained ) - 它说“只要其他人强烈地指向它就保持它” - 与赋值相同,不保留或释放 - “弱”引用是您不保留的引用。- 我们一般对IBOutlets(UIViewController 的Childs)使用weak。这是因为子对象只需要在父对象存在时就存在。-弱引用是不保护被引用对象不被垃圾收集器收集的引用。-Weak 本质上是赋值,一种未保留的属性。除了对象被释放时,弱指针自动设置为 nil
Example :
例子 :
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@synthesize myButton;
Strong & Weak Explanation, Thanks to BJ Homer:
强弱解释,感谢 BJ Homer:
Imagine our object is a dog, and that the dog wants to run away (be deallocated). Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached. Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it. As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out. When we use weak? The only time you would want to use weak, is if you wanted to avoid retain cycles (e.g. the parent retains the child and the child retains the parent so neither is ever released).
试想一下,我们的对象是狗,而狗要跑掉(被释放)。强指针就像狗的皮带。只要你把皮带拴在狗身上,狗就不会逃跑。如果五个人将他们的皮带拴在一只狗上(五个强烈的指针指向一个物体),那么在所有五根皮带都松开之前,狗不会逃跑。另一方面,弱指针就像小孩子指着狗说“看!一只狗!” 只要狗仍然被拴在皮带上,小孩子仍然可以看到狗,他们仍然会指向它。然而,一旦所有的皮带都松开了,不管有多少小孩指着它,这只狗都会逃跑。一旦最后一个强指针(leash)不再指向一个对象,该对象将被释放,所有弱指针将被清零。当我们使用弱?您唯一想要使用弱的情况是,如果您想避免保留循环(例如,父项保留子项而子项保留父项,因此两者都不会被释放)。
- retain= strong -it is retained, old value is released and it is assigned -retain specifies the new value should be sent -retain on assignment and the old value sent -release -retain is the same as strong. -apple says if you write retain it will auto converted/work like strong only. -methods like "alloc" include an implicit "retain"
- 保留=强-它被保留,旧值被释放,它被分配-retain指定的新值应在分配和旧值发送-retain发送-release -retain是一样强。-apple 说如果你写保留它会自动转换/像强一样工作。-像“alloc”这样的方法包括一个隐含的“保留”
Example:
例子:
@property (nonatomic, retain) NSString *name;
@synthesize name;
- assign-assign is the default and simply performs a variable assignment -assign is a property attribute that tells the compiler how to synthesize the property's setter implementation -I would use assign for C primitive properties and weak for weak references to Objective-C objects.
- 分配-assign是默认设置,只需执行一个变量赋值-assign是财产属性,它告诉编译器如何合成属性的setter的实现-我会用分配对C基本属性和弱弱引用Objective-C对象。
Example:
例子:
@property (nonatomic, assign) NSString *address;
@synthesize address;
unsafe_unretained
-unsafe_unretained is an ownership qualifier that tells ARC how to insert retain/release calls -unsafe_unretained is the ARC version of assign.
unsafe_unretained
-unsafe_unretained 是所有权限定符,它告诉 ARC 如何插入保留/释放调用 -unsafe_unretained 是分配的 ARC 版本。
Example:
例子:
@property (nonatomic, unsafe_unretained) NSString *nickName;
@synthesize nickName;
- copy-copy is required when the object is mutable. -copy specifies the new value should be sent -copy on assignment and the old value sent -release. -copy is like retain returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments. -if you use copy then you still need to release that in dealloc. -Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
- 当对象是可变的时,需要copy-copy。-copy 指定应该发送新值 -copy 分配和发送旧值 -release。-copy 就像保留返回一个对象,您必须在非垃圾收集环境中明确释放(例如,在 dealloc 中)。- 如果你使用 copy 那么你仍然需要在 dealloc 中释放它。- 如果您需要当前对象的值,并且您不希望该值反映该对象的其他所有者所做的任何更改,请使用此选项。完成后您需要释放对象,因为您保留了副本。
Example:
例子:
@property (nonatomic, copy) NSArray *myArray;
@synthesize myArray;
回答by Kannan Prasad
Atomic property can be accessed by only one thread at a time. It is thread safe. Default is atomic .Please note that there is no keyword atomic
原子属性一次只能被一个线程访问。它是线程安全的。默认是 atomic 。请注意没有关键字 atomic
Nonatomicmeans multiple thread can access the item .It is thread unsafe
非原子意味着多个线程可以访问该项目。它是线程不安全的
So one should be very careful while using atomic .As it affect the performance of your code
所以在使用 atomic 时应该非常小心。因为它会影响代码的性能
回答by Ahmad Abbas
prefer this links about properties in objective-c in iOS...
更喜欢这个关于iOS中objective-c属性的链接......
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html