2

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

如果我有一个对象,可以说:

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

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

谢谢

4

3 回答 3

2

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

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

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

于 2012-06-04T18:41:05.673 回答
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)的开销是非常小的。当然,您不必这样做,但这是一种很好的做法。

于 2012-06-04T19:06:30.103 回答
1

回答您的问题:不,属性和综合调用不会分配任何内存。你必须这样做。如果你不这样做, 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% 正确,因为保留属性的合成设置器如下所示:

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

最后一点与帕特里克的回答有关,不建议在 init 方法中使用设置器。所以而不是

self.myString = @"xyz";

建议直接访问 iVar:

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

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

于 2012-06-05T19:54:23.273 回答