簡體   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