iOS内存管理问题

时间:2012-01-29 19:13:56

标签: ios memory-management release-management iboutlet

当您使用Xcode的功能并从nib文件拖放到.h和.m文件时,Xcode会在deallocviewDidUnload中添加代码。它添加了我通常不添加的额外代码。我很好奇是否需要这些额外的代码。

我会完成[self setDisplaySlider:nil]而不是disp = nil[disp release]

这有必要吗?我不认为你必须释放disp。

@interface ViewController : UIViewController
{
   IBOutlet UISegmentedControl *disp;    
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

- (void)viewDidUnload
{
    [self setDisplaySlider:nil];
    [disp release];
    disp = nil;
    [super viewDidUnload];
}

- (void)dealloc {
    [displaySlider release];
    [disp release];
    [super dealloc];
}

2 个答案:

答案 0 :(得分:3)

在我看来,你提供了一个额外代码的课程。我会试着解释一下。

首先,在您之前,您有两个不同的IBOutlet。我认为你已经添加了第一个。

IBOutlet UISegmentedControl *disp;

当您进行拖放操作时,Xcode会添加第二个。

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

首先考虑

术语IBOutlet只是Xcode的占位符。通过它,Xcode可以帮助您将实例变量连接到图形元素。

当我使用插座连接时,我通常会提供像@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;这样的访问器(如Xcode所做的那样),因为如果没有,你可能会遇到内存泄漏问题。

第二个考虑因素

Xcode提供的代码是对的。进行拖动操作时,您将displayController实例变量与图形元素链接在一起。要平衡此连接,必须在dealloc方法中释放该实例变量,如下所示:

[displayController release];

相反,Xcode添加了[self setDisplaySlider:nil];,因为在内存警告情况下可以调用viewDidUnload方法。这里没问题,因为当控制器再次装入内存时,插座连接会恢复。

可以在Advanced Memory Management docrelease-or-set-to-nil-retained-members中读取两个方法调用之间的差异。请注意,如果您这样做:

[displayController release];

您可以直接访问名为displayController的实例变量,如果您这样做:

[self setDisplaySlider:nil]; // or self.displaySlider = nil;

您可以访问该实例变量的访问者(在本例中为setter方法)。它不一样(为了避免混淆,请参阅我提供的代码)。

所以,这是我要使用的代码(我添加了一些注释来指导你):

//.h
@interface ViewController : UIViewController
{
    UISegmentedControl *disp; // instance variable called disp
    // (A) now this is no longer necessary, new compile mechanism will create an instance
    // variable called _displaySlider under the hood
}

@property (retain, nonatomic) IBOutlet UISegmentedControl *displaySlider;

@end

//.m
@synthesize displaySlider = disp;  // I say to Xcode to create a setter and a getter to access the instance variable called disp as written in @property directive
// no longer necessary for (A)

- (void)viewDidUnload
{
    [super viewDidUnload];        
    [self setDisplaySlider:nil]; // I call the setter method to release the UISegmentedControl
}

- (void)dealloc {
    [disp release]; // I release the UISegmentedControl directly
    // if you choose the (A) mechanism simply do
    // [_displaySlider release];
    [super dealloc];
}

希望它有所帮助。

答案 1 :(得分:0)

看看你的viewDidLoad:我认为你会发现这些物品正在那里分配。

您需要将此与viewDidUnload中的版本进行平衡,否则如果再次加载视图,则会在未被释放的情况下再次分配对象,并且您将会泄漏。