Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 以编程方式创建的子视图和viewDidUnload_Iphone_Objective C_Ios_Memory Management - Fatal编程技术网

Iphone 以编程方式创建的子视图和viewDidUnload

Iphone 以编程方式创建的子视图和viewDidUnload,iphone,objective-c,ios,memory-management,Iphone,Objective C,Ios,Memory Management,对于视图控制器,必须释放在Interface Builder中设置的所有插座 在viewDidUnload中设置为nil,并且必须在dealoc中释放 (见:) 实现[viewDidUnload]的最重要原因之一是UIViewController子类通常还包含对视图层次结构中各种子视图的拥有性引用。例如,当从nib加载时,这些属性可以通过IBOutlets设置,或者在loadView中以编程方式设置 我的问题是,我们真的需要为视图层次结构中的子视图实现viewDidUnload,这些子视图是在l

对于视图控制器,必须释放在Interface Builder中设置的所有插座 在viewDidUnload中设置为nil,并且必须在dealoc中释放

(见:)

实现[viewDidUnload]的最重要原因之一是UIViewController子类通常还包含对视图层次结构中各种子视图的拥有性引用。例如,当从nib加载时,这些属性可以通过IBOutlets设置,或者在loadView中以编程方式设置


我的问题是,我们真的需要为视图层次结构中的子视图实现viewDidUnload,这些子视图是在loadView中以编程方式创建的(没有界面生成器)?

使用
dealoc
方法实现。无法保证将调用
viewDidUnload
。它通常仅在控制器需要卸载视图时调用,例如,当出现内存警告时。另一方面,将始终调用
init
/
dealloc
配对。

这取决于您如何创建它们以及是否需要在其他地方引用它们

例如:

- (void)loadView
{
    [super loadView];

    UIButton *someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}
- (void)loadView
{
    [super loadView];

    self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}
在上述情况下,您不需要实现viewDidUnload,因为someButton在loadView中自动删除

另一个例子:

- (void)loadView
{
    [super loadView];

    UIButton *someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}
- (void)loadView
{
    [super loadView];

    self.someButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    someButton.frame = CGRectMake(0, 0, 50, 50);
    [self.view addSubview: someButton];
}
在本例中,您可能希望使用viewDidUnload,因为您有另一个对挂起的someButton的引用。您希望viewDidUnload释放该按钮并重置引用,这样您就不会不正确地使用它并释放内存。在这种情况下,您还需要释放dealloc方法中的按钮,以防从未调用viewDidUnload。

您当然应该这样做。然而,如果你仔细查看苹果的样本,你会发现有时候它们只是使用dealloc。如果你知道你的物品会在使用后的某个合理时间被释放,我认为这是完全合理的。但是,我遵循这种模式,因为在某些特殊情况下可能不会调用viewDidUnload。我实际上并没有用这么长的名字来称呼release方法:

-(void)releaseRetainedXibAndViewDidLoadObjects
{
    self.myLabel = nil;
    self.myImage = nil;
}

-(void)viewDidUnload
{
    [super viewDidUnload];
    [self releaseRetainedXibAndViewDidLoadObjects];
}

-(void)dealloc
{
    self.myObject = nil;
    [self releaseRetainedXibAndViewDidLoadObjects];
    [super dealloc];
}

您甚至可以从一个特定于应用程序的视图控制器对象执行此操作,您的类将其子类化以简化问题。

我将在Dealoc中发布我的子视图。我是否也必须释放我的子视图,并在viewDidUnload中将它们设置为nil?@Seth Lowenstein:这要看情况而定。从文档中可以看出:“您应该只对以后可以在viewDidLoad方法中或从应用程序的其他部分轻松重新创建的对象执行此操作。您不应该使用此方法发布用户数据或无法轻松重新创建的任何其他信息”调用相同的“发布方法”是否明智在viewDidUnload和dealloc*中?通常,我们将@property设置为“(nonatomic,retain)”,因此为您创建的setter将释放当前对象,然后保留参数。也就是说,
self.myProperty=nil执行类似于
[myProperty release];myProperty=[nil retain]。。。然后,在dealoc中,我们所做的就是
[myProperty release]
。使用我的模式是完全安全的,并且没有必要在dealoc中与在viewDidUnload中进行不同的操作。对于保留的属性self.property=nil相当于[property release],property=nil;尽管在dealloc中将其设置为nil并不重要,但如果您稍后无意中尝试访问它,这仍然是一个好主意。您应该减少冗余,减少必须定义相同功能的位置的数量。这是完全正确的!其思想是,视图控制器应该能够经历许多loadView(+viewDidLoad)/viewDidUnload周期,而不会泄漏内存或访问僵尸。最好的例子是选项卡栏控制器中的VCs-它们被分配一个,然后在单击选项卡时通过loadView/viewDidUnload在自定义loadView方法中不应调用[super loadView]。代码如下:self.view=[[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame]autorelease];想解释一下为什么五宝?我从未遇到过调用[super loadView]的问题。