发布UIView

时间:2012-03-12 11:41:58

标签: iphone objective-c ios uiview

注意:澄清我在这里要做的事情:

我有一个UIView子类的实例。当此实例从View Controller中释放时,我希望调用该实例的dealloc方法。

要点在UIView的子类的实例中释放其他对象。

在视图控制器中:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.mav = [[MapAreaView alloc]init];
    [self.view addSubview:self.mav];
    [self.mav release];

    t_ = [NSTimer scheduledTimerWithTimeInterval: 20.0f target: self selector:@selector(onTick) userInfo: nil repeats:NO];
}

- (void)onTick
{
    NSLog(@"Releasing...");
    [t_ invalidate];
    t_ = nil;
    [self.mav release];
    [self.mav release];
    [self.mav release];
    NSLog(@"Done releasing.");
}

在MapAreaView中:

- (void)dealloc
{
    NSLog(@"map view area dealloc called.");
    [super dealloc];
}

我正在尝试发布MapAreaView并调用它的dealloc方法。

此外,当我运行此应用时,Releasing...Done releasing.会被打印,但不会map view area dealloc called。尽管我将所有过多的释放消息发送到self.mav,但应用程序不会崩溃。怪异。

想法?

编辑1

@interface MemoryManagmentViewController : UIViewController {

    MapAreaView *mav_;
    NSTimer *t_;
}

@property (nonatomic, retain) MapAreaView *mav;

然后合成:@synthesize mav = mav_;

编辑2

请注意,计时器不适用于我的实际应用程序。我只是用它来学习内存管理。

5 个答案:

答案 0 :(得分:2)

首先,请勿使用[self.mav release]。这是对属性的错误使用,并不保证释放您的对象。请改用self.mav = nil

其次,我认为你的疯狂计时器只是试图强制释放你的视图,而不是你正在使用的代码?因为它真的不应该在那里!

要管理要保留指针并将其作为子视图添加到主视图的视图的内存,请从viewDidLoad中删除发布和计时器消息。您现在通过您的属性有一个保留指向mav的指针,并且视图将保留它,因为它是子视图。

在viewDidUnload中,您的视图不再存在,因此它将不再具有指向mav的指针。因此,如果您将self.mav = nil放在那里,mav将被释放。

当它仍然是另一个视图的子视图时,你不应该尝试释放它。

答案 1 :(得分:2)

您无法在dealloc运行时选择

您不知道iOS框架中还有哪些内容会保留您的地图视图。

你应该考虑所有权方面的内存管理 - 当你想要一个对象时,确保你retained它(明确地或作为一个属性),当你完成它时,请确保你释放它(通过致电releaseautorelease或将您的财产设置为nil来启动它。

你的地图视图最终会被释放,不要试图强迫它!

(并且在许多其他答案中已经说过,但它非常重要,所以在这里再次 - 不要拨打self.property release,而是self.property = nil;代替:)

*对于您自己编写的库中的对象来说并不完全正确,但对于来自第三方框架的对象(包括来自Apple的对象)来说肯定是正确的!

答案 2 :(得分:0)

该行:

[self.view addSubview:self.mav];

将保留self.mav,并且应与onTick中的此行配对。

[self.mav removeFromSuperview];

我不确定为什么你在onTick中的过度释放不会释放self.mav - 但如果你做了奇怪的事情,你可以保证会发生奇怪的事情。

答案 3 :(得分:0)

请勿再次在onTick内发布。执行以下两个步骤:

[self.mavview removeFromSuperView];
self.mavview = nil;

就是这样。将不再有任何参考,因此将被解除分配。

答案 4 :(得分:-1)

首要的是 永远不要在self.iVar上发布释放

分配时不要使用用户self.iVar。

这些是内存管理的基本内容。