2011-11-10 116 views
0

我宣佈以下變量作爲實例變量,並在我的m文件中使用它,但是我收到警告。Obj-C,在線分配的對象的潛在泄漏,警告?

TransparentToolbar *tools; 

就行分配的對象的潛在泄漏...

我曾嘗試創建一個屬性,例如..

@property (nonatomic, retain) TransparentToolbar *tools; 

而且synthesize'ing並將其釋放,但是我的觀點在dealloc結束時崩潰了。

我在做什麼錯?

編輯在pickerSortingDataCurrent同樣的警告......

h 
@interface myViewController : UIViewController <UIActionSheetDelegate, 
    UIPickerViewDelegate, UIPickerViewDataSource, UITableViewDelegate, 
    UITableViewDataSource, MFMailComposeViewControllerDelegate> { 

    TransparentToolbar *tools; 

    NSArray *pickerSortingDataCurrent; 
} 
@property (nonatomic, retain) TransparentToolbar *tools; 
@property (nonatomic, retain) NSArray *pickerSortingDataCurrent; 

m 
@synthesize pickerSortingDataCurrent; 
@synthesize tools; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    tools = [[[TransparentToolbar alloc] 
      initWithFrame:CGRectMake(0, 0, 70, 44.01)] autorelease]; 
    tools.barStyle = UIBarStyleBlackOpaque; 

    self.pickerSortingDataCurrent = [[NSArray alloc] initWithObjects: 
     @"Next Date Ascending", 
     @"Next Date Descending", nil];  // removed some items here 
} 

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

AHHHH我已經自動釋放....但這並不解決pickerSortingDataCurrent ...

編輯...

#import "TransparentToolbar.h" 

@implementation TransparentToolbar 

- (void)drawRect:(CGRect)rect { 
    // do nothing in here 
} 

- (void) applyTranslucentBackground 
{ 
    self.backgroundColor = [UIColor clearColor]; 
    self.opaque = NO; 
    self.translucent = YES; 
} 

- (id) init 
{ 
    self = [super init]; 
    [self applyTranslucentBackground]; 
    return self; 
} 

// Override initWithFrame. 
- (id) initWithFrame:(CGRect) frame 
{ 
    self = [super initWithFrame:frame]; 
    [self applyTranslucentBackground]; 
    return self; 
} 

@end 

其他編輯 enter image description here

+0

很難不代碼說。 – Max

+0

你可以包含你的'dealloc'代碼嗎? – Jef

+0

我遇到了同樣的問題,我在viewDidLoad中填充了一個接口數據數組,請參閱上面的編輯。 – Jules

回答

5

如果您定義了@property,那麼通常您在任何時候訪問您的課堂中的ivar時,都可以使用getter/setter,無論是點符號還是標準方法調用。

點標記

id localyMyVar = self.myVar; 
self.myVar = @"A string"; 

標準方法調用

id localMyVar = [self myVar]; 
[self setMyVar:@"A string"]; 

如果你總是明確地使用這些getter和setter方法,那麼你幾乎不需要在你的代碼的任何地方調用release除了dealloc或重寫的setMyVar:方法。這樣做可以讓內存管理在有限的地方發生。如果你開始釋放和保持自己,那麼當你第一次出發時,事情會變得有點複雜。

UPDATE

@bbum給你答案,但我認爲你會被你的編碼以及更多洽受益。

例如,在不使用setter的情況下直接分配給ivar的違規行之前。保持一致並使用你花費時間綜合的setter/getter。我會改寫

tools = [[[TransparentToolbar alloc] 
     initWithFrame:CGRectMake(0, 0, 70, 44.01)] autorelease]; 
tools.barStyle = UIBarStyleBlackOpaque; 

TransparentToolbar *tmpTools = [[TransparentToolbar alloc] initWithFrame:CGRectMake(0, 0, 70, 44.01)]; 
tmpTools.barStyle = UIBarStyleBlackOpaque; 
self.tools = tmpTools; 
[tmpTools release]; tmpTools = nil; 

init方法是不是真的以下任你應該檢查self實際的指導方針,所以它應該類似於東西:

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

UPDATE

你在這裏看到的內存泄漏:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.tools]; 

是因爲你在看文檔爲UINavigationItem你會看到rightBarButtonItem被聲明爲retain

@property(nonatomic, retain) UIBarButtonItem *rightBarButtonItem 

因此通話self.navigationItem.rightBarButtonItem將採取A + 1保留在你傳入的對象上,然後你是alloc/initing,這是另一個+1保留。 UINavigationItem將在釋放時釋放它的保留,但仍會保留原始保留。

的修復:

UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.tools]; 
self.navigationItem.rightBarButtonItem = rightBarButtonItem; 
[rightBarButtonItem release]; rightBarButtonItem = nil; 
+0

我仍然收到由此行引發的警告'self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.tools];' – Jules

+0

請參閱屏幕拍攝 – Jules

0

如果您創建了一個retain屬性,則必須將其設置爲你的dealloc方法爲零。

@interface DMFakeyClass : NSObject 

@property (nonatomic, retain) NSString *bogusString; 

@end 

@implementation DMFakeyClass 

-(void)dealloc { 
    self.bogusString = nil; 
    [super dealloc]; 
} 

@end 

這幾乎是所有你需要做的有一個成功的存儲管理策略。當您使用此屬性時,請始終使用getter/setter(self.bogusString = [NSString stringWithString:@"bogus"];)並確保您已經自動發佈或發佈了您分配的任何內容(self.bogusString = [[[NSString alloc] initWithString:@"bogus2"] autorelease];)。按照這種模式,你不應該有任何問題。

1
self.pickerSortingDataCurrent = [[NSArray alloc] initWithObjects: 
    @"Next Date Ascending", 
    @"Next Date Descending", nil];  // removed some items here 

+1保留爲+ ALLOC計數+1保留計數分配到retain@property

重寫成:

NSArray *labels = [[NSArray alloc] initWithObjects: 
    @"Next Date Ascending", 
    @"Next Date Descending", nil]; 
self.pickerSortingDataCurrent = labels; 
[labels release]; 

(或者你可以使用autorelease

+0

在看到上面的評論之前,這仍然給我一個警告。 – Jules