1
  1. 在属性的 getter 函数(即自动生成)中name,对象是否返回如下?

    [self.name autorelease]; 
    return self.name;
    
  2. 在setter函数中(也是自动生成的),retained对象是autoreleased吗?-

    - (void) setName : (NSString *) someString {
        [someString retain];
        [name release];
        name = someString;
        /* [someString autorelease]; */ // performed internally?
    }
    

#import<Foundation/Foundation.h>

@interface Dog : NSObject
{@private NSString * name;}
@property (nonatomic,retain) NSString * name;
@end

@implementation Dog
@synthesize name;
- (id) init {
    self = [super init];
    if(self) {}
    return self;
}
@end

int main(int argc, char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    Dog * d = [[Dog alloc] init];
    [d setName:@"Scooby"];
    NSLog(@"Dog's name is: %@",[d name]);
    [d release];
    [pool drain];
    return 0;
}
4

2 回答 2

3

不会。您要求的自动释放将释放名称并导致访问冲突,因为名称中的对象不会被保留。如果 getter 在返回对象之前保留该对象,则它可以返回一个自动释放的对象:return [[name retain] autorelease];。这可能需要完成以支持从多个线程进行访问,但在这种情况下,getter 和 setter 中需要某种线程同步。

为了使您的代码在非 ARC 中正确,它需要有一个释放名称的 dealloc 方法。

- (void)dealloc
{
    [name release];
    [super dealloc];
}

这里有一些关于自动生成代码的讨论。

于 2013-07-23T16:53:31.577 回答
2

回答你的两个问题:

  1. getter 不应该autorelease是对象。

  2. setter 不应该autorelease指向新值的对象someString

Anautorelease实际上是 deferred release,因此 getter 或 setter 都不适合这样做。当然,setter 会release使用旧对象,但它肯定不应该autorelease使用新对象。


顺便说一下,最后的三个观察结果:

  • 您不应该编写自己的 setter 和 getter,除非有迫切需要这样做。如果你只是想了解他们在做什么,那很好,但在实践中,我们很少编写自己的访问器方法。

  • 此外,我衷心鼓励您使用 ARC(如果可以的话)。

  • 如果出于某种原因使用 Xcode 并使用手动引用计数,请务必通过静态分析器(Xcode“产品”菜单上的“分析”)运行您的代码,因为它会指出许多使用autorelease.


如果将 gcc 与 GNUStep 一起使用,您的Dog类可能如下所示:

@interface Dog : NSObject
{
    NSString *_name;
}

@property (nonatomic, copy) NSString *name;

@end

@implementation Dog

@synthesize name = _name;

- (id)init
{
    self = [super init];
    if (self) {
        _name = nil;
    }
    return self;
}

- (void)dealloc
{
    [_name release];
    [super dealloc];
}

@end

请注意,没有定义访问器方法(它们是为我合成的)。

虽然 gcc 不支持它,但如果您使用的是较新的编译器,则可以省略 ivar 声明和以下@synthesize行:

@interface Dog : NSObject

@property (nonatomic, copy) NSString *name;

@end

@implementation Dog

- (id)init
{
    self = [super init];
    if (self) {
        _name = nil;
    }
    return self;
}

- (void)dealloc
{
    [_name release];
    [super dealloc];
}

@end

或者如果使用 ARC,您甚至可以省略init方法(因为 ARC 将对象初始化为nil)和dealloc方法(因为 ARC 显然会自动释放对象):

@interface Dog : NSObject

@property (nonatomic, copy) NSString *name;

@end

@implementation Dog

@end
于 2013-07-23T19:36:42.473 回答