ios Objective-C 101(保留与分配)NSString
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1380338/
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
Objective-C 101 (retain vs assign) NSString
提问by qstar
A 101 question
一个 101 题
Let's say i'm making database of cars and each car object is defined as:
假设我正在制作汽车数据库,每个汽车对象定义为:
#import <UIKit/UIKit.h>
@interface Car:NSObject{
NSString *name;
}
@property(nonatomic, retain) NSString *name;
Why is it @property(nonatomic, retain) NSString *name;
and not @property(nonatomic, assign) NSString *name;
?
为什么是@property(nonatomic, retain) NSString *name;
而不是@property(nonatomic, assign) NSString *name;
?
I understand that assign
will not increment the reference counter as retain
will do. But why use retain
, since name
is a member of the todo
object the scope of it is to itself.
我知道这assign
不会像那样增加引用计数器retain
。但是为什么要使用retain
,因为它是对象的name
成员todo
,它的作用域是它自己。
No other external function will modify it either.
其他外部函数也不会修改它。
回答by Chuck
There's no such thing as the "scope of an object" in Objective-C. Scope rules have nothing to do with an object's lifetime — the retain count is everything.
Objective-C 中没有“对象的范围”这样的东西。范围规则与对象的生命周期无关——保留计数就是一切。
You usually need to claim ownership of your instance variables. See the Objective-C memory management rules. With a retain
property, your property setter claims ownership of the new value and relinquishes ownership of the old one. With an assign
property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. The reason you would use an assign
property is in a case where you can't retain the value (such as non-object types like BOOL or NSRect) or when retaining it would cause unwanted side effects.
您通常需要声明您的实例变量的所有权。请参阅Objective-C 内存管理规则。对于retain
财产,您的财产设置者声称拥有新值的所有权并放弃旧值的所有权。对于一个assign
属性,周围的代码必须这样做,这在职责和关注点分离方面同样混乱。使用assign
属性的原因是在无法保留值的情况下(例如 BOOL 或 NSRect 等非对象类型),或者保留它会导致不必要的副作用。
Incidentally, in the case of an NSString, the correct kind of property is usually copy
. That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it isa kind of NSString).
顺便说一句,在 NSString 的情况下,正确的属性类型通常是copy
. 这样,如果有人传入一个 NSMutableString(这是有效的——它是一种 NSString),它就不会从你下面改变。
回答by Axel
and don't forget to access it via
并且不要忘记通过访问它
self.name = something;
because
因为
name = something;
will not care about the generated setter/getter methods but instead assign the value directly.
不会关心生成的 setter/getter 方法,而是直接分配值。
回答by fbrereto
Without retain
there is no guarantee the NSString*
you are setting name
with will live any longer than the assignment statement itself. By using the retain
property for the synthesized setter you're allowing it to tell the memory management system that there is at least one more object interested in keeping the NSString*
around.
如果没有retain
,则无法保证NSString*
您设置name
的内容会比赋值语句本身的寿命更长。通过使用retain
合成 setter的属性,您允许它告诉内存管理系统至少还有一个对象有兴趣保持NSString*
周围。
回答by tbone
回答by jem
The self.
in:
该self.
在:
self.name = something;
is important! Without it, you are accessing the variable directly and bypassing the setter.
很重要!没有它,您将直接访问变量并绕过 setter。
The older style (correct me if I am wrong) would have been:
较旧的样式(如果我错了,请纠正我)应该是:
[self setName:something];
Anyway, this notation was the (vaguely familiar sounding) advice that I really needed when I went looking for proper @properties
on NSStrings
. Thanks Axel.
无论如何,这个符号是我在寻找正确@properties
的NSStrings
. 谢谢阿克塞尔。
回答by swiftBoy
After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together
在阅读了这么多文章、SO 帖子并制作了演示应用程序来检查变量属性属性后,我决定将所有属性信息放在一起
- atomic //default
- nonatomic
- strong=retain //default
- weak= unsafe_unretained
- retain
- assign //default
- unsafe_unretained
- copy
- readonly
- readwrite //default
- 原子 //默认
- 非原子的
- 强=保留//默认
- 弱 = unsafe_unretained
- 保持
- 赋值 //默认
- unsafe_unretained
- 复制
- 只读
- 读写 //默认
so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you. Many thanks to all the people who give best answers here!!
所以下面是详细的文章链接,您可以在其中找到上述所有属性,这将对您有所帮助。非常感谢所有在这里给出最佳答案的人!!
- 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 分配和发送旧值 -release
- 保留与强相同。
- 苹果说如果你写保留它只会自动转换/像强一样工作。
- 像“alloc”这样的方法包括一个隐含的“retain”
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 原始属性使用assign,对Objective-C 对象的弱引用使用weak。
Example:
例子:
@property (nonatomic, assign) NSString *address;
@synthesize address;
回答by funroll
Google's Objective-C Style Guidecovers this pretty well:
Google 的Objective-C 风格指南很好地涵盖了这一点:
Setters taking an NSString, should always copy the string it accepts. Never just retain the string. This avoids the caller changing it under you without your knowledge. Don't assume that because you're accepting an NSString that it's not actually an NSMutableString.
使用 NSString 的 Setter 应该始终复制它接受的字符串。永远不要只保留字符串。这可以避免调用者在您不知情的情况下更改它。不要因为你接受一个 NSString 而认为它实际上不是一个 NSMutableString。
回答by Dan Ray
Would it be unfortunate if your class got this string object and it then disappeared out from under it? You know, like the second time your class mentions that object, it's been dealloc'ed by another object?
如果你的班级得到了这个字符串对象,然后它从它下面消失了,那会不会很不幸?你知道吗,就像你的班级第二次提到那个对象时,它已经被另一个对象释放了?
That's why you want to use the retain
setter semantics.
这就是为什么要使用retain
setter 语义的原因。