【问题标题】:Do I still have to alloc my object if I'm using a property如果我使用属性,我还需要分配我的对象吗
【发布时间】:2012-06-08 19:52:35
【问题描述】:

简单的问题,我似乎找不到快速的帖子;

如果我有一个对象,让我们说:

 NSString *myString_;
 @property(readwrite, retain)NSString* myString;
 @synthesize myString = myString_; 

当我合成这个时,它会为对象分配内存吗?

谢谢

【问题讨论】:

标签: objective-c memory-management properties


【解决方案1】:

没有。您将分配和初始化一个对象,然后将属性设置为它,ala:

self.myString = [[NSString alloc] initWithString: @"Hello Miek"];

或者您将拥有一个已分配和保留的字符串,您将把新属性设置为。

【讨论】:

    【解决方案2】:

    @synthesize 所做的只是为您的属性生成访问器(setter 和 getter)并创建一个具有相同名称的实例变量。使用等号的新增步骤:

    @synthesize mystring = _string;
    

    ... 为您将实例变量重命名为 _string (或您选择的任何名称,下划线只是苹果约定)。这是一个很好的做法,因为让实例变量与访问器共享相同的名称可能会出现问题。拥有下划线可以让您区分两者。

    这基本上是生成的(假设 ARC 为 ON):

    // getter
    - (NSString*)mystring
    {
        return _string;
    }
    

    // setter
    - (void)setMyString:(NString*)myString
    {
        _myString = myString;
    }
    

    您可以在 init 方法中初始化您的属性(使用 self.propertyName):

    -(id)init
    {
        self.myString = @"Something"; // or use an alloc init method in the class   
    }
    

    或者你可以像这样覆盖getter来懒惰地初始化它:

    - (NSString*)myString
    {
        if (!_myString) {  // same as saying if nil and therefore doesn't exist yet
            _myString = @"Something";
        }
        return _myString;
    }
    

    还请注意,您不需要单独声明变量(即您不需要 NSString* mystring)。声明属性时,只需使用 strong 或 weak 代替 retain。

    您应该直接访问实例变量的唯一位置是在访问器中,这允许您通过单个网关控制对其的所有操作。在类中使用访问器(即 self.mystring)的开销非常小。当然,您不必这样做,但这是一种很好的做法。

    【讨论】:

      【解决方案3】:

      回答您的问题:不,property 和 synthesize 调用不会分配任何内存。你必须这样做。如果你不这样做, myString 实际上在构造时指向 nil 。 不过不要使用 Michael 的示例,因为它会泄漏内存。

      使用

      self.myString = @"Hello Miek";
      

      @字面量其实相当于调用[NSString stringWithString:]类方法 它返回一个自动释放(当然也是分配的)对象。或者你可以使用这个

      NSString *aString = [[NSString alloc] initWithString: @"string...."];
      self.myString = aString;
      [aString release];
      

      另外请注意,您应该将属性声明为副本,而不是为 NSStrings 保留。 在你的 dealloc 中,你也必须释放 myString。

      最后,Patrick 的回答并非 100% 正确,因为保留属性的合成 setter 如下所示:

      -(void) setMyString: (NSString*) string {
          [myString release];
          myString = [string retain];
       }
      

      最后一点与帕特里克的回答有关,不建议在 初始化方法。所以而不是

      self.myString = @"xyz";
      

      建议直接访问iVar:

      //or _myString, if you synthesized it that way of course
      myString = @"xyz";
      [myString retain];
      

      干杯(长答案,我手头有一点时间;)

      【讨论】:

      • props 用于发布内存管理的访问器实现;我的回答假设用户在启用了 ARC 的 iOS5 上,调用 release 或 retain 将在 ARC 打开时失败。另请阅读我上面关于直接在访问器外部访问 iVar 的更新。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 2022-11-20
      • 1970-01-01
      • 2021-10-24
      相关资源
      最近更新 更多