这是我的情况:我有一个 UIViewController
管理 subview 的层次结构,可能如下所示:
此 View 是根据 .xib
构建的。我希望能够维护对 topView 的每个 subview 的访问 - 也就是说,我想要一个指向每个 subview 的指针,以便我可以说:
[button1 setText:@"Hello!"];
通常,为了做到这一点,我会使用 Interface Builder 连接我想要访问的每个元素,从而产生如下所示的 header :
@interface MyViewController : UIViewController
{
__weak IBOutlet UIView *view;
__weak IBOutlet UILabel *label;
__weak IBOutlet UIButton *button1;
__weak IBOutlet UIButton *button2;
}
@end
这些实例变量是__weak
,这很好,因为当我的 View Controller “获取”它们时,它们已经属于我的 View Controller 的 Root View (令人困惑的是,我在快速图表中标记为“topView”)。事实上,我希望这些引用是弱的——当我的 Root View 被释放时,它的所有 subview 也应该被释放。太棒了。
但是假设我想创建一个新的 UI 元素,也许是一个自定义按钮,完全用代码编写。我将这个元素称为 CustomViewClass
,将从 UIView
派生子类。 CustomViewClass
的实例我将创建的名称将被称为 customButton
。与我的 View 的其他 subview 一样,我希望“访问”customButton
这样我就可以与它互动。然而,我知道,就像任何其他 subview 一样,customButton
将由其 super View 拥有,这就是它应该的样子 - 再次,我希望每当我的 View 发布时它都会被发布。这让我认为我应该将此 View 声明为 __weak
我的 View Controller 的实例变量或属性。让我们这样做:
@interface MyViewController : UIViewController
{
__weak IBOutlet UIView *view;
__weak IBOutlet UILabel *label;
__weak IBOutlet UIButton *button1;
__weak IBOutlet UIButton *button2;
__weak CustomViewClass *customButton;
}
@end
然后,在我的实现中:
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
customButton = [[CustomViewClass alloc] init];
[[self view] addSubview:customButton];
}
@end
正如您可能已经意识到的那样,这是行不通的,编译器会在启动时抛出警告。像这样的东西:
Assigning retained object to weak variable; object
will be released after assignment
我目前用一些非常糟糕的风格来躲避这种警告:
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CustomViewClass *customButtonLocal = [[CustomViewClass alloc] init];
[[self view] addSubview:customButtonLocal];
customButton = customButtonLocal;
}
@end
这样,我就得到了我想要的:
- 屏幕上的 CustomViewClass 实例...
- ...只有一个所有者,其 super View ...
- ...并且没有挥之不去的变量(customButtonLocal 在 block 结束后立即释放)。
但这不可能是“正确”的方法。最后,我的问题是:
我应该如何分配和实例化这个以编程方式创建的 __weak
变量而不使用这个中间人解决方法?
最佳答案
制造CustomViewClass *customButton
具有很强的引用意义。
通常将 subview 的变量声明为 __weak IBOutlet
的原因是这些链接的存在并不意味着所有权。 subview 由从 NIB/Storyboard 实例化的对象拥有。您直接拥有该对象,并且还间接拥有其依赖对象。
customButton
是一个不同的故事:您以编程方式创建它,因此您的 NIB/Storyboard 不拥有它。因此,您应该引用它 __strong
(这是没有 ARC 修饰符时的默认设置)。
关于objective-c - 在 View Controller 中维护 subview 的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11314392/