objective-c - 在 View Controller 中维护 subview 的链接

标签 objective-c ios uiview uiviewcontroller

这是我的情况:我有一个 UIViewController管理 subview 的层次结构,可能如下所示:

View hierarchy

此 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

这样,我就得到了我想要的:

  1. 屏幕上的 CustomViewClass 实例...
  2. ...只有一个所有者,其 super View ...
  3. ...并且没有挥之不去的变量(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/

相关文章:

iphone - 在 FTP 上上传多个文件

objective-c - 相对日期格式,过去日期的输出?

iphone - 为什么我的 UIPickerView 崩溃了?

ios - Flutter ios应用程序提交: Missing Purpose String in Info. plist

ios - RGB颜色不正确?

ios - 如何在 iOS 上向谷歌地图标记信息窗口添加按钮?

ios - SBJSON ios 5 或原生苹果 JSON

ios - 如何使用 flutter 在 iOS 中测试验证 InAppPurchase

iphone - 如何获得一个 UIView,它在边界更改时显示文本,使其表现得像 UILabel 一样?

iphone - 在某些 UIView 之外检测触摸事件