内存:对象在视图控制器关闭后不会释放,使用ARC

时间:2013-11-29 07:34:38

标签: ios objective-c memory-management viewcontroller

我有2个视图控制器,

FirstViewController - > SecondViewController通过

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

memory graph

我在做

时在SecondViewContrller上

[self dismissViewControllerAnimated:YES completion:nil];

enter image description here

我的问题是,在解除此viewcontroller后,为什么对象不会在secondViewController上释放。正如您在图表中看到的那样,在解雇后它没有下降。 BTW有什么最好的方式来释放/解散ViewController?

[编辑]

我在每个VC上使用dealloc方法记录消息,当我从FVC-> SVC-> [解除SVC]开始时。这是我的日志

enter image description here

6 个答案:

答案 0 :(得分:8)

这可能是非常粗糙的东西。我以前遇到过类似的问题。搜索您的代码,看看您是否对对象有强烈或错误的引用。

我最大的错误之一(以及我在互联网上看过几百次)是委托属性。很长一段时间我都像@property (nonatomic, retain) id<protocol>delegate;一样编写它们,因为我意识到如果我这样做,委托对象就不会被释放。在这种情况下,必须使用assign

希望能帮到你......

答案 1 :(得分: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

  

正如你所看到的,在pressMeButtonAction调用了secondViewController后,调用了pressDissmissButtonAction后,secondViewController被成功解除分配。

     

但是:大部分时间它会立即解除分配,但是如果你很快出现并解散它(每秒两次左右),则不会立即解雇,但过了一会儿。

     

我假设这是ARC解除分配程序的设计实现。不确定。

答案 2 :(得分:0)

试试这个......

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

SVC = nil;

答案 3 :(得分:0)

在花了很多时间之后,我终于发现了一个缺失的难题:你不仅需要将对ViewController的任何强引用设置为nil,你还必须使任何定时器无效并且注意到阻止保留周期。 每当你在一个块中使用self时,你就会创建一个保留周期!相反,你应该声明一个像这样的变量

__unsafe_unretained ViewController *weakSelf = self; 

并在块中使用它而不是self。

答案 4 :(得分:0)

检查应用程序中的所有IBOutlet。可能会为他们分配“强大”属性。让他们“软弱”。例如,IBOulet应该是这样的:

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

检查应用程序中的所有代表(如果有)。每个代表都应该是这样的:

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

请注意,ARC需要一些时间来恢复内存。

答案 5 :(得分:0)

在我的案例中,定时器是个问题。添加了对viewWillDisappear无效的计时器,然后释放了视图控制器。