2013-11-29 2 views
11

У меня есть 2 контроллер представления,Память: объект не отпускают после просмотра контроллера увольте, с ARC

FirstViewController -> SecondViewController через

[self presentViewController:SVC animated:YES completion:nil]; 

memory graph

на SecondViewContrller когда я

[self dismissViewControllerAnimated:YES completion:nil]; 

enter image description here

Мой вопрос в том, почему объекты не выпускаются на secondViewController после того, как я уволил этот диспетчер представлений. Как вы можете видеть на графике Он не спустился после увольнения. BTW - лучший способ опубликовать/закрыть ViewController?

[EDIT]

Я NSLog сообщение о методе dealloc на каждом VC, когда я начать с FVC-> SVC -> [закрыть SVC]. это мои журналы

enter image description here

+0

Вы правильно распределили viewcontroller. дать вашему viewcontroller init alloc code – codercat

+0

SecondViewController * SVC = [[SecondViewController alloc] initWithNibName: @ "SecondViewController" bundle: nil]; – Bordz

+3

Вы можете реализовать метод dealloc во втором контроллере представления и поставить там точку останова (или 'NSLog'). ARC не означает немедленное освобождение. – Marc

ответ

0

попробовать это ...

[self presentViewController:SVC animated:YES completion:nil]; 

SVC = nil; 
+0

Вы не можете отправлять сообщения 'release' при использовании ARC. –

+0

oops я пропустил термин ARC, так можно отредактировать работу ответа? –

8

Это может быть довольно грубый материал. Раньше у меня были подобные проблемы. Найдите свой код и посмотрите, есть ли у вас сильные или неправильные ссылки на объекты.

Одна из моих главных ошибок (и то, что я видел в Интернете сотни раз) - это свойства делегата. Я написал их как @property (nonatomic, retain) id<protocol>delegate; довольно долго, поскольку понял, что если я это сделаю, делегированный объект не будет выпущен. В этом случае нужно использовать assign.

Надеется, что поможет вам ...

+0

Привет, спасибо за ваши мысли, НО в моем случае я не делал делегатов, выход, протокол и т. Д. Это просто простой контроллер. Моя точка зрения заключается в том, чтобы действительно проверить управление памятью при отключении VC. – Bordz

2

Я сделал некоторые исследования с этим поведением.

FirstViewController.m

#import "FirstViewController.h" 
#import "SecondViewController.h" 

@interface FirstViewController() 

@end 

@implementation FirstViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
    // Custom initialization 
} 
    return self; 
} 

-(void)dealloc { 
    NSLog(@"First Dealloc"); 

} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.view.backgroundColor = [UIColor redColor]; 
    UIButton *pressMe=[UIButton buttonWithType:UIButtonTypeCustom]; 
    pressMe.frame = CGRectMake(0, 0, 100, 40); 
    pressMe.center = self.view.center; 
    [pressMe setTitle:@"PressMe" forState:UIControlStateNormal]; 
    [pressMe addTarget:self action:@selector(pressMeAction:)    
    forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:pressMe]; 

// Do any additional setup after loading the view. 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

-(void) pressMeAction:(id) sender 
{ 
    SecondViewController *svc = [[SecondViewController alloc] init]; 
    [self presentViewController:svc animated:YES completion:nil]; 
    NSLog(@"Present Second"); 
} 

@end 

SecondViewController.m

довольно же, за исключением

-(void) pressDissmissButtonAction:(id) sender 
{ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
    NSLog(@"Dismiss Second"); 
} 

и это динамика Распределение enter image description here

Как вы можете видеть после нажатия кнопкиMeButtonAction, вызывается secondViewController, выделенный и после нажатия вызывающего secondSecurityButtonAction secondViewController успешно освобождается.

BUT: В большинстве случаев он освобождается немедленно, но если вы представляете и отклоняете его очень быстро (дважды в секунду или около того), то выделение не запускается немедленно, а через некоторое время.

Я предполагаю, что это путем реализации процедуры освобождения ARC. Не уверен.

+0

Невозможно реализовать метод '-dealloc' с включенным ARC. –

+6

Это неверно. Вы не должны вызывать delloc on super при использовании ARC. https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc –

+0

делает ваш NSlog методом dealloc на FirstVC вышел? – Bordz

0

Потратив много времени на это, я наконец-то нашел недостающий кусок головоломки: Мало того, что вы должны установить какие-либо сильные ссылки на ViewController к нулю, вы должны также аннулировать любые таймеры и знать циклов сохранения блоков. Каждый раз, когда вы используете себя в блоке, вы создаете цикл сохранения! Вместо этого вы должны объявить такую ​​переменную

__unsafe_unretained ViewController *weakSelf = self; 

и использовать его вместо себя в блоке.

+0

Спасибо за эту информацию. Не могли бы вы предоставить скриншот для диаграммы памяти, в которой он будет сбрасываться после отключения SecondViewController – Bordz

0

Проверьте все IBOutlets в своем приложении. Для них может быть «сильное» свойство. Сделайте их «слабыми». Например, IBOulet должно быть так:

@property (weak, nonatomic) IBOutlet UILabel *myLabel; 

Проверьте все делегаты (если таковые имеются) в вашем приложении. Каждый делегат должен быть таким:

@property (nonatomic, assign) id <yourProtocol> delegate; 

Обратите внимание, что для восстановления памяти требуется некоторое время для ARC.

0

Таймеры были проблемой в моем случае. Добавленный таймер недействителен для viewWillDisappear, и диспетчеры представлений были затем выпущены.

Смежные вопросы