2013-09-28 40 views
1

我一直在開發一個應用程序大約一週左右,現在我認爲這將是一個好時機來分析它,以確保我做的一切正確,什麼是什麼我發現,即使我的所有對象都被分配了,分配量也在增加。當我釋放物體我執行以下操作:對象似乎被釋放,但內存佔用不斷上升

[object release]; 
object = nil; 

在我的應用程序我有確定任一示出了初始視圖控制器我LoginViewControllerTimeLineViewController,取決於我是否有訪問令牌。 (這部分不重要,因爲我遇到的問題在LoginViewController/SignupViewController之內。)。登錄控制器有兩個文本框和兩個按鈕,這些按鈕將sVC推到導航視圖控制器上或嘗試登錄。

奇怪的是,我的視圖和視圖控制器上正在調用dealloc方法,但內存在調用之後會上升。

SDK 7.0版 的Xcode 5.0版本

編輯:

在我LoginViewController當我從一個LoginView該SignupButton已被點擊的情況下,本方法被稱爲:

- (void)signupButtonPressed 
{ 
    SignupViewController *signupVC = [[SignupViewController alloc] init]; 
    [self.navigationController pushViewController:signupVC animated:true]; 
    destroy(signupVC); 
} 

***注意,破壞宏如下:

#define destroy($x)            \ 
if($x)               \ 
{                \ 
[$x release];            \ 
$x = nil;             \ 
} 

當SignupViewController創建viewDidLoad方法如下:

self.view = [[SignupView alloc] initWithFrame:self.view.frame]; 

    [[(SignupView *)self.view evtSignupButtonPressed] addHandler:AFFHandler(@selector(signupPressed))]; 
    [((SignupView *)self.view).profileImage addTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside]; 

[self.navigationController setNavigationBarHidden:false animated:true]; 

然後創建看起來像這樣對於內部SignupView視圖的用戶界面:

- (void)setupUI 
{ 

    self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:IS_IPHONE5 ? @"genericBackground-568h.jpg" : @"genericBackground.jpg"]]; 

    _overlayView = [[UIView alloc] initWithFrame:self.frame]; 

    _scrollView = [[UIScrollView alloc] initWithFrame:self.frame]; 


    _profileImage = [[UIButton alloc] init]; 

    profileImageContainer = [[UIView alloc] initWithFrame:CGRectMake(18.5, 0, _profileImage.imageView.image.size.width + 10, _profileImage.imageView.image.size.height + 10)]; 


    selectProfilePictureText = [[UILabel alloc] initWithFrame:CGRectMake(profileImageContainer.affX, 0, 229, 17)]; 


    UIView *padding = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 17, 40)]; 

    _usernameField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)]; 
    _usernameField.delegate = self; 

    _passwordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)]; 
    _passwordField.delegate = self; 

    _repeatPasswordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)]; 

    _repeatPasswordField.delegate = self; 

    _emailField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)]; 
    _emailField.delegate = self; 

    destroy(padding); 

    buttonImage = [[UIImage imageNamed:@"largeButton.png"] copy]; 
    _submitButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height)]; 
    [_submitButton addTarget:self action:@selector(signupButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 


    destroy(buttonImage); 




    [self addSubview:_scrollView]; 
    [self addSubview:_overlayView]; 
    [_scrollView addSubview:profileImageContainer]; 
    [profileImageContainer addSubview:_profileImage]; 
    [_scrollView addSubview:selectProfilePictureText]; 

    [_scrollView addSubview:_usernameField]; 
    [_scrollView addSubview:_passwordField]; 
    [_scrollView addSubview:_repeatPasswordField]; 
    [_scrollView addSubview:_emailField]; 
    [_scrollView addSubview:_submitButton]; 


    destroy(profileImageContainer); 
    destroy(selectProfilePictureText); 

} 

** A音符,伊夫省略所有改變這些對象屬性的代碼,如改變backgroundColour等等。

的SignupVC和SignupView的dealloc的方法如下:

SignupView:

- (void)dealloc 
{ 

    self.usernameField.delegate = nil; 
    self.passwordField.delegate = nil; 
    self.repeatPasswordField.delegate = nil; 
    self.emailField.delegate = nil; 

    AFFRemoveAllEvents(); 

    destroyAndRemove(_usernameField); 
    destroyAndRemove(_passwordField); 
    destroyAndRemove(_repeatPasswordField); 
    destroyAndRemove(_emailField); 
    destroyAndRemove(_profileImage); 
    destroyAndRemove(_submitButton); 
    destroyAndRemove(_scrollView); 
    destroyAndRemove(_overlayView); 

    if(buttonImage) 
     destroy(buttonImage); 


    [super dealloc]; 
} 

SignupVC(這被按下導航欄的後退按鈕之後調用)

- (void)dealloc 
    { 
     [[(SignupView *)self.view evtSignupButtonPressed] removeHandlersForObserver:self]; 
     [((SignupView *)self.view).profileImage removeTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside]; 
     destroy(profileImage); 
     destroyAndRemove(self.view); 


     [super dealloc]; 
    } 

DestroyAndRemove是這樣做的:

#define destroyAndRemove($x)         \ 
if($x)               \ 
{                \ 
[$x removeFromSuperview];         \ 
[$x release];            \ 
$x = nil;             \ 
} 
+0

對象是否包含對外部資源的任何引用?是基於垃圾收集,參考計數的內存管理方案嗎?不要碰巧知道這個環境。 – joshp

+3

你在看什麼樂器? – RyanR

+0

那是Objective-C的代碼嗎?如果是這樣,請添加一個objective-c標籤。我認爲'[object release]'與C中的'free()'函數類似。如果是這樣,釋放內存使其可以在程序中進一步分配;它並不一定會減少程序佔用的內存大小。 –

回答

5

切換到ARC。嚴重的是,沒有充分的理由不使用它,它可能會修復你的內存問題,甚至:

1)蘋果公司強烈鼓勵並表示他們在更新和新應用程序中使用ARC

2)絕大多數新的應用程序提交和更新使用ARC,它已被證明在絕大多數情況下與手動引用計數一樣高效(您的應用程序可能並不是例外) 。

3)ARC簡化了您作爲Objective-C開發人員的生活。您不必亂丟release,retain等代碼。

4)有一個易於使用的轉換工具:

轉到Edit>Refactor>Convert to Objective C ARC

5)即使您使用的是沒有切換到尚未ARC第三方庫(最受歡迎已經有),你可以選擇不使用ARC個人文件。有關如何操作,請參閱其他SO post

如果你還在切換到ARC之後問題 - 如前所述,切換到ARC可能會解決您的記憶issues-回來,我們就會給這個別的去了。

+0

不正確地回答這個問題,但絕對是一個明智的建議。 +1 –

+1

如果他切換到'ARC',並解決了他的問題,我會將其稱爲問題的答案。 :D –

+0

這是在黑暗中拍攝的一種,但是是的^^ –

4

什麼對象正在增加?

即,使用分配工具時,請打開「僅跟蹤活動對象」(或等效命名的功能)。然後使用您的應用程序,並查看哪些對象在內存中不應該存在。打開參考事件跟蹤器。

更可能的是,它是一個保留週期。也許一個強大的引用你的對象的計時器?或者其他一些類似的關係。

一旦確定了內存中存在的對象,則應該點擊進入保留和釋放清單並查看哪些內容不平衡。

請注意,您確實應該使用ARC。

+1

我已經完成了這個工作,但沒有任何Views或ViewControllers在內存中存在。唯一可能導致這種情況的是委託給我的自定義警報框,但它被設置爲弱(我爲了測試目的而更改爲ARC),並且在分配之前並且在警報框被解除時設置爲零。 – ApperleyA

+1

然後呢,什麼樣的分配呢?按「實時記憶」排序。在某個地方必須有一些分配。或者,它可能映射與圖像等相關的內存。 – bbum