Objective-C 101(保留vs赋值)NSString

时间:2009-09-04 16:40:18

标签: ios objective-c iphone nsstring retain

一个101问题

假设我正在制作汽车数据库 每个汽车对象定义为:

#import <UIKit/UIKit.h>

@interface Car:NSObject{
    NSString *name;
}

@property(nonatomic, retain) NSString *name;

为什么是@property(nonatomic, retain) NSString *name;而不是@property(nonatomic, assign) NSString *name;

我了解assign不会像retain那样增加引用计数器。但是为什么要使用retain,因为nametodo对象的成员,它的范围就是它自己。

其他任何外部功能都不会修改它。

8 个答案:

答案 0 :(得分:68)

Objective-C中没有“对象的范围”这样的东西。范围规则与对象的生命周期无关 - 保留计数就是一切。

您通常需要声明实例变量的所有权。见the Objective-C memory management rules。使用retain属性,您的属性设置器声明新值的所有权并放弃旧值的所有权。使用assign属性,周围的代码必须执行此操作,这在责任和关注点分离方面同样混乱。您将使用assign属性的原因是您无法保留该值(例如BOOL或NSRect等非对象类型),或者保留它会导致不必要的副作用。

顺便说一下,在NSString的情况下,正确的属性通常是copy。这样,如果有人传入NSMutableString(它是有效的 - 是一种NSString),它就无法从你身下改变。

答案 1 :(得分:19)

并且不要忘记通过

访问它
self.name = something;

,因为

name = something;

不关心生成的setter / getter方法,而是直接赋值。

答案 2 :(得分:12)

如果没有retain,则无法保证NSString* name设置retain的时间超过赋值语句本身。通过对合成setter使用NSString*属性,您可以让它告诉内存管理系统至少还有一个对象需要保留{{1}}。

答案 3 :(得分:9)

对于那些正在寻找它的人,Apple关于属性属性的文档是here

答案 4 :(得分:9)

self. in:

self.name = something;

很重要!没有它,您将直接访问变量并绕过setter。

旧样式(如果我错了,请纠正我)本来是:

[self setName:something];

无论如何,这个符号是我在@properties寻找合适NSStrings时真正需要的(含糊不清的声音)建议。谢谢阿克塞尔。

答案 5 :(得分:8)

在阅读了如此多的文章,SO帖子和制作演示应用以检查变量属性属性后,我决定将所有属性信息放在一起

  1. atomic // default
  2. 非原子
  3. strong = retain // default
  4. weak = unsafe_unretained
  5. 保留
  6. assign // default
  7. unsafe_unretained
  8. 复制
  9. 只读
  10. readwrite // default
  11. 以下是详细的文章链接,您可以在其中找到上述所有属性,这些属性将极力帮助您。 非常感谢所有在这里给出最佳答案的人!!

      

    Variable property attributes or Modifiers in iOS

    1. retain = strong
      • 保留,旧值被释放并被分配
      • retain指定应在发送时发送新值-retain,并发送旧值-release
      • 保留与强者相同。
      • apple说如果你写保留它会自动转换/工作就像强大。
      • 像“alloc”这样的方法包含一个隐含的“retain”
    2. 示例:

      @property (nonatomic, retain) NSString *name;
      
      @synthesize name;
      
      1. 指定
        • assign是默认值,只是执行变量赋值
        • assign是一个属性属性,告诉编译器如何合成属性的setter实现
        • 我会使用assign表示C原语属性,而weak表示弱对Objective-C对象的引用。
      2. 示例:

        @property (nonatomic, assign) NSString *address;
        
        @synthesize address;
        

答案 6 :(得分:3)

Google的Objective-C Style Guide非常清楚:

  

Setters采用NSString,应该始终复制它接受的字符串。   永远不要只保留字符串。这可以避免调用者在您不知情的情况下将其更改为您。不要假设因为你接受的NSString实际上并不是NSMutableString。

答案 7 :(得分:2)

如果你的班级得到这个字符串对象然后它从它下面消失了,那会不幸吗?你知道,就像你的班级第二次提到那个对象一样,它被另一个对象解除了吗?

这就是你想要使用retain setter语义的原因。