如果我正在使用属性,是否还需要分配我的对象

时间:2012-06-04 18:38:41

标签: objective-c memory-management properties

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

如果我有一个对象,请说:

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

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

由于

3 个答案:

答案 0 :(得分:2)

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

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

或者你已经分配了&保留字符串,您将设置新属性。

答案 1 :(得分: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)。在宣布财产时,只需使用强或弱代替保留。

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

答案 2 :(得分:1)

回答你的问题:不,属性和合成调用不会分配任何内存。你必须这样做。如果不这样做,myString在构造时实际上指向nil。 不要使用迈克尔的例子,因为它泄漏了记忆。

使用

self.myString = @"Hello Miek";

@ literal实际上等同于调用[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];
 }

在与Patrick的答案有关的最后一个注释中,不建议使用setter init方法。所以而不是

self.myString = @"xyz";

建议直接访问iVar:

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

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