繁体   English   中英

Objective-C中的内存管理

[英]Memory Management in Objective-C

我想问我是否在该类中分配了一个实例变量供私有使用,应该立即在现场释放它,还是可以依赖于dealloc函数。 (因为也许我将在其他功能上需要它)?

//Player.h
@interface Player : NSObject
{
    NSMutableArray * objectArray;
}

- (void)awake;
- (void)add;

@end

//Player.m
@implementation Player : NSObject
{
    -(id) init {
        self = [super init];
        if (self !=  nil ){
            [self awake];
            [self add];
        }
        return self;
    }
    - (void) awake {
        objectArray = [[NSMutableArray alloc] init]; //is it cause leakage?
        [objectArray addObject:@"foobar"];
    }
    - (void) add {
        [objectArray addObject:@"foobar2"];
    }
    - (void) dealloc {
        [objectArray release];
        [super dealloc];
    }
}

@end

还是我应该使用属性来设置objectArray iVar?

//Player.h
@interface Player : NSObject
{
    NSMutableArray * objectArray;
}

@property (nonatomic,retain)NSMutableArray* objectArray;

- (void)awake;
- (void)add;

@end

//Player.m
@implementation Player : NSObject
{
    -(id) init {
        self = [super init];
        if (self !=  nil ){
            [self awake];
            [self add];
        }
        return self;
    }
    - (void) awake {
        self.objectArray = [[NSMutableArray alloc] init autorelease]; //cause leakage?
        [objectArray addObject:@"foobar"];
    }
    - (void) add {
        [objectArray addObject:@"foobar2"];
    }
    - (void) dealloc {
        [objectArray release];
        [super dealloc];
    }
}

@end

如果它们都不引起泄漏,我应该使用哪种类型? 我是否应该始终设置iVar属性,并且即使我只想在此类中使用它,也可以通过self访问iVar值?

我想采取的立场是,如果实例变量在类外部不可见,则不应将其实现为属性。 但这是其他开发人员可能不同意的事情。

无论哪种方式,您都需要在类的dealloc方法中释放objectArray-这是您当前正在执行的操作。

但是,您需要注意awake方法-如果多次调用它,则objectArray会泄漏。 这是不使用属性的缺点。 在这里使用self.objectArray = [[NSMutableArray alloc] init]会释放先前的对象。

我认为,仅当允许其他对象使用属性时,才应在标头中声明属性。 没有充分的理由说明为什么要提供一个-add:方法(如您的示例),该方法将一些内容添加到您的数组中,同时还为该数组提供了一个getter方法,以便其他对象可以直接对其进行操作。 这就是所谓的封装。

如果确实希望为实现文件利用生成的getter / setter的好处,则可以始终在实现文件中使用类继承(无名称类别),并在其中包括属性声明。 这样,您将获得真正的,自动生成的属性,这些属性仅对您的类的实现可见。

就个人而言,我不会在您的示例中使用任何getter或setter方法。 只需在-init中分配NSArray并在-dealloc中释放它。 如果您的-awake方法可能被多次调用,只需添加一个[objectArray removeAllObjects]调用,您肯定会拥有一个空数组,而不必担心内存管理。

在第一个示例中,内存很可能会泄漏,因为您没有将release发送到先前设置的实例变量(如果已经存在)。

这就是为什么您应该使用属性设置器-它们会为您处理所有这些事情的原因。

此外,由于你是通过属性获取实例变量的所有权(这与确定的retain关键字),你肯定会泄漏内存,如果你不发送实例变量-release你的消息-dealloc方法。

因此,结论是您应该使用第二个示例,而不是第一个示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM