4

我有 2 个问题。

首先- 在 obj-c 中是否这样声明字符串

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *city;

这些是(nonatomic, copy)正确的还是我应该使用(nonatomic, strong),或者别的什么?

第二- 如果我想为上述字符串设置自定义初始化程序,我是否使用

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    self = [super init];
    if (self) {
        self.name = n;
        self.city = c;
    }
}

或者我应该使用:

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    self = [super init];
    if (self) {
        self.name = [n copy]
        self.city = [c copy];
    }
}

正如我所看到的,这两种方法似乎都适用于这两个问题,但我确信一种方法比另一种更正确,所以我想问我应该使用哪种方法在进一步的项目中编写正确的代码。

谢谢。

4

2 回答 2

13

您想copy用于值语义类型的属性。(其中NSString始终是一个。)否则,我可以向您传递一个实例,NSMutableString然后在事后将其从您的下方更改。不可变对象将-copyWithZone:通过做来实现return [self retain];以免在不需要时实际创建第二个副本。另请参阅:NSString 属性:复制还是保留?

就您的-init方法而言,您希望避免像您一样使用属性设置器,因为它们可能会在子类中被覆盖以执行您的类无法预料的事情。所以假设默认的 auto-ivar-synthesis 命名模式,你会想要这样做:

-(id)initWithName:(NSString *)n andCity:(NSString *)c
{
    if (self = [super init])
    {
        _name = [n copy];
        _city = [c copy];
    }
    return self;
}

这是一件微妙的事情,通常不会成为问题,但如果你继续在-init-dealloc方法中使用固有的虚拟属性设置器,在足够长的时间线上,你被这个烧毁(你能告诉我一直被这个烧了?)

至于泄漏的内存,如果您使用 ARC,则执行类似self.foo = [bar copy];when foo 是copy属性的操作导致复制被调用两次,并且可能会制作两个副本,但 ARC 应该注意正确释放冗余/中间副本,并且应该有内存泄漏。

于 2013-10-04T12:09:28.647 回答
0

copy首先 - 使用or并不重要strong。我个人更喜欢复制字符串而不是保留它们

第二个-`

-(id)initWithName:(NSString *)n andCity:(NSString *)c

   {
      self = [super init];
       if (self) {
          self.name = n;
          self.city = c;
  }
}`

您不需要再次使用copy消息,因为您的属性将复制 n 和 c。如果您应用第二段代码,您将复制 n 和 c 两次并发生内存泄漏

于 2013-10-04T11:57:09.123 回答