用户界面的内存管理

Memory Management For User Interface

我正在处理一个应用程序的用户界面,而且我是以编程方式进行的。我理解保留循环背后的想法,并且非常有信心我可以确定一个,但是 Xcode 在我试图避免保留循环时给我警告。

基本上,我正在创建一个名为 titleLabel 的 属性,它将具有我的标题,在 viewDidLoad 中,我正在初始化它,并将其放在我的视图中。唯一的问题是,我收到一条 Xcode 警告:

Assigning retained object to weak variable; object will be released after assignment

我的属性定义如下:

@property (nonatomic, weak) UILabel *titleLabel;

显然我可以通过在我的 属性 定义中将 weak 更改为 strong 来修复 Xcode 警告,但我相信这会创建一个保留周期(来自我的理解)因为按钮在视图控制器上,视图控制器在按钮上。

谁能告诉我如何正确执行此操作?

我认为您可以将 属性 设置为 strong 以保留其内存,当您的视图将消失时,您可以将此对象设置为 nil 以释放其内存。

你的理解有问题。如果标签要保留对其视图控制器的引用,如果 属性 定义为 strong,您将有一个保留周期。但是,视图不保留对其视图控制器的引用,因此不存在循环。 Xcode 正确地警告您,您的标签引用将在分配后消失。您甚至不会通过将其添加为子视图(这会保留它)来保存它,因为它已经在您尝试时发布了。

视图不保留对控制器的引用的一个准例外是 table 和集合视图,它们具有委托和数据源,通常是它们的管理视图控制器。然而,那些 delegate/datasource 属性被定义为 assign 属性(它有另一组问题)所以那里也没有保留周期。

当您创建 UI 元素并将其作为子视图添加到父视图时。父视图保持对子视图的强引用。在您的情况下,您可以在函数中创建一个 UILabel 变量并将其添加到父级。

然后您可以声明一个弱 属性 来保留对这个新创建的标签的引用。这样,父视图 "owns" 标签,并在父视图离开屏幕时负责清理标签。

@interface MasterViewController ()

@property (nonatomic,weak) UILabel * theLabel;

@end

@implementation MasterViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    [self.view addSubview:myLabel];
    self.theLabel = myLabel;
}