以下是我的情况:我有UIViewController
来管理子视图的层次结构,可能如下所示:
此视图是根据.xib
构建的。我希望能够保持对topView的每个子视图的访问 - 也就是说,我想要一个指向每个子视图的指针,以便我可以例如说:
[button1 setText:@"Hello!"];
通常,为此,我使用Interface Builder连接我想要访问的每个元素,从而生成如下所示的标题:
@interface MyViewController : UIViewController
{
__weak IBOutlet UIView *view;
__weak IBOutlet UILabel *label;
__weak IBOutlet UIButton *button1;
__weak IBOutlet UIButton *button2;
}
@end
这些实例变量是__weak
,这很好,因为当我的视图控制器“获取”它们时,它们已经被我的视图控制器的根视图所拥有(令人困惑的是,我将其标记为“topView”在我的快速图中)。事实上,我希望这些引用很弱 - 当我的根视图被释放时,它的所有子视图也应该被释放。大。
但是,假设我想创建一个UI的新元素,可能是一个自定义按钮,完全在代码中。我将调用此元素CustomViewClass
,它将从UIView
创建子类。我将创建的CustomViewClass
实例将被称为customButton
。与我的观点的其他子视图一样,我希望“访问”customButton
以便我可以与之交互。但是,我知道,就像任何其他子视图一样,customButton
将由其超级视图拥有,而它应该如何 - 再次,我希望每当我的视图发布时它都会被释放。这让我觉得我应该将此视图声明为我的视图控制器的__weak
实例变量或属性。我们这样做:
@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
这样,我得到了我想要的东西:
但这不是“正确”的做法。最后,我的问题是:
应该如何我在不使用这个中间人解决方法的情况下分配和实例化这个以编程方式创建的__weak
变量?
答案 0 :(得分:2)
使CustomViewClass *customButton
成为强有力的参考。
您通常将子视图的变量声明为__weak IBOutlet
的原因是这些链接的存在并不意味着所有权。子视图由从NIB / Storyboard实例化的对象拥有。您直接拥有该对象,并且您还间接拥有其依赖对象。
customButton
是一个不同的故事:您以编程方式创建它,因此您的NIB / Storyboard不拥有它。因此,您应该引用它__strong
(这是没有ARC修饰符时的默认值)。