简体   繁体   English

Objective-C中的内存管理

[英]Memory Management in Objective-C

I wanna ask if I allocated an instance variable for private use in that class, should i release it immediately on site, or i can depend on dealloc function. 我想问我是否在该类中分配了一个实例变量供私有使用,应该立即在现场释放它,还是可以依赖于dealloc函数。 (because maybe i will need it on other function) ? (因为也许我将在其他功能上需要它)?

//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

or should i using property to set the objectArray iVar? 还是我应该使用属性来设置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

if both of them doesn't cause a leakage, what type should i use? 如果它们都不引起泄漏,我应该使用哪种类型? should i always set iVar property, and access iVar value with self even if i only want to use it in this class? 我是否应该始终设置iVar属性,并且即使我只想在此类中使用它,也可以通过self访问iVar值?

I like to take the stance that if the instance variable should not be visible outside of the class then it should not be implemented as a property. 我想采取的立场是,如果实例变量在类外部不可见,则不应将其实现为属性。 But it's a personal thing that other developers may not agree with. 但这是其他开发人员可能不同意的事情。

Either way you would need to release the objectArray in your classes dealloc method - which is what you're currently doing. 无论哪种方式,您都需要在类的dealloc方法中释放objectArray-这是您当前正在执行的操作。

However you need to be careful with your awake method - if it's invoked multiple times then objectArray is leaked. 但是,您需要注意awake方法-如果多次调用它,则objectArray会泄漏。 This is the downside of not using properties. 这是不使用属性的缺点。 A use of self.objectArray = [[NSMutableArray alloc] init] here would have released the previous object. 在这里使用self.objectArray = [[NSMutableArray alloc] init]会释放先前的对象。

In my opinion, you should only declare properties in your header if other objects are allowed to use them. 我认为,仅当允许其他对象使用属性时,才应在标头中声明属性。 There is no good reason why you would provide an -add: method (as in your example) that adds something to your array while also providing a getter for your array so other objects can manipulate it directly. 没有充分的理由说明为什么要提供一个-add:方法(如您的示例),该方法将一些内容添加到您的数组中,同时还为该数组提供了一个getter方法,以便其他对象可以直接对其进行操作。 It's called encapsulation. 这就是所谓的封装。

If you do want to have the benefits of generated getters/setters for your implementation file, you can always use a class continuation (a nameless category) inside your implementation file and include your property declarations there. 如果确实希望为实现文件利用生成的getter / setter的好处,则可以始终在实现文件中使用类继承(无名称类别),并在其中包括属性声明。 That way you get real, auto-generated properties that are only visible to your class' implementation. 这样,您将获得真正的,自动生成的属性,这些属性仅对您的类的实现可见。

Personally, I wouldn't use any getter or setter methods in your example. 就个人而言,我不会在您的示例中使用任何getter或setter方法。 Just allocate the NSArray in your -init and release it in -dealloc. 只需在-init中分配NSArray并在-dealloc中释放它。 If this -awake method of yours might be called multiple times, just add an [objectArray removeAllObjects] call and you're sure to have an empty array without worrying about memory management. 如果您的-awake方法可能被多次调用,只需添加一个[objectArray removeAllObjects]调用,您肯定会拥有一个空数组,而不必担心内存管理。

It is very likely that memory will leak in your first example because you are not sending release to the previously set instance variable (if it already existed). 在第一个示例中,内存很可能会泄漏,因为您没有将release发送到先前设置的实例变量(如果已经存在)。

This is why you should use property setters - they handle all of this stuff for you. 这就是为什么您应该使用属性设置器-它们会为您处理所有这些事情的原因。

Also, since you are obtaining ownership of the instance variable through the property (which is defined with the retain keyword), you will definitely leak memory if you don't send the instance variable the -release message in your -dealloc method. 此外,由于你是通过属性获取实例变量的所有权(这与确定的retain关键字),你肯定会泄漏内存,如果你不发送实例变量-release你的消息-dealloc方法。

So the verdict is that you should use the second example, not the first. 因此,结论是您应该使用第二个示例,而不是第一个示例。

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

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