简体   繁体   English

Objective-C 101(保留与分配)NSString

[英]Objective-C 101 (retain vs assign) NSString

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; 为什么是@property(nonatomic, retain) NSString *name; and not @property(nonatomic, assign) NSString *name; 而不是@property(nonatomic, assign) NSString *name; ?

I understand that assign will not increment the reference counter as retain will do. 我知道assign不会像retain一样增加参考计数器。 But why use retain , since name is a member of the todo object the scope of it is to itself. 但是为什么要使用retain ,因为nametodo对象的成员,所以它的范围就是它自己。

No other external function will modify it either. 其他任何外部功能也不会对其进行修改。

There's no such thing as the "scope of an object" in Objective-C. 在Objective-C中,没有“对象范围”之类的东西。 Scope rules have nothing to do with an object's lifetime — the retain count is everything. 范围规则与对象的生存期无关—保留计数就是一切。

You usually need to claim ownership of your instance variables. 通常,您需要声明实例变量的所有权。 See the Objective-C memory management rules . 请参阅Objective-C内存管理规则 With a retain property, your property setter claims ownership of the new value and relinquishes ownership of the old one. 有了retain财产,您的财产设定者会要求拥有新价值,而放弃旧价值。 With an assign property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. 使用assign属性,周围的代码必须执行此操作,就责任和关注点分离而言,情况同样如此。 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. 使用assign属性的原因是在无法保留该值的情况下(例如BOOL或NSRect等非对象类型),或者在保留该值时会导致不良的副作用。

Incidentally, in the case of an NSString, the correct kind of property is usually copy . 顺便说一句,对于NSString,通常正确的属性是copy That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it is a kind of NSString). 这样,如果有人传入NSMutableString(这是有效的-这一种NSString),它就不会从您的下方改变。

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方法,而是直接分配值。

Without retain there is no guarantee the NSString* you are setting name with will live any longer than the assignment statement itself. 如果没有retain ,则不能保证您设置nameNSString*寿命将比赋值语句本身更长。 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. 通过对合成的setter使用retain属性,您可以让它告诉内存管理系统至少还有一个对象有兴趣保留NSString*

对于那些正在寻找它的人,Apple的属性属性文档在这里

The self. self. in: 在:

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 . 无论如何,这种表示法是我在NSStrings上寻找适当的@properties时真正需要的(有点熟悉的听起来)建议。 Thanks Axel. 谢谢阿克塞尔。

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帖子并制作了演示应用程序以检查Variable属性后,我决定将所有属性信息放在一起

  1. atomic //default 原子//默认
  2. nonatomic 非原子
  3. strong=retain //default strong =保留//默认
  4. weak= unsafe_unretained 弱=不安全_未保留
  5. retain 保留
  6. assign //default 分配//默认
  7. unsafe_unretained unsafe_unretained
  8. copy 复制
  9. readonly 只读
  10. readwrite //default readwrite //默认

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!! 非常感谢在这里给出最佳答案的所有人!!

Variable property attributes or Modifiers in iOS iOS中的可变属性属性或修饰符

  1. 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 保留指定新值应发送-保留分配和旧值发送-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" 像“分配”这样的方法包括一个隐式的“保留”

Example: 例:

@property (nonatomic, retain) NSString *name;

@synthesize name;
  1. 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 Assign是一个属性属性,它告诉编译器如何综合该属性的setter实现
    • I would use assign for C primitive properties and weak for weak references to Objective-C objects. 我将对C基本属性使用assign,对Objective-C对象的弱引用使用weak。

Example: 例:

@property (nonatomic, assign) NSString *address;

@synthesize address;

Google's Objective-C Style Guide covers this pretty well: Google的《 Objective-C风格指南》涵盖了以下方面:

Setters taking an NSString, should always copy the string it accepts. 使用NSString的设置者应始终复制其接受的字符串。 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实际上不是NSMutableString。

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设置器语义的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM