【问题标题】:Retain object without using a property保留对象而不使用属性
【发布时间】:2015-06-01 01:48:40
【问题描述】:

我有一个像这样工作的控件:

MyCustomControl *control = [[MyCustomControl alloc] initWithNavigationController:self.navigationController];

control.completion = ^{
    [self controlCompletedAction];
};

[control showFromView:self.view];

但是,由于它没有被任何东西保留,因此在尝试调用某些方法时,控件的访问权限不正确。

在调用类的属性中保留控件可以正常工作,例如:

@property(nonatomic, strong) MyCustomControl *control;

@interface MyViewController {
    MyCustomControl *control;
}

两者都可以正常工作。

但是,我不想为我正在制作的每个不同控件添加属性。 控件的目的是分离功能以避免大量的视图控制器。该属性不对视图控制器中的任何其他内容负责,因此没有理由保留它。

那么,有没有办法使用属性/ivar 或诉诸 objc 运行时来保留控件

【问题讨论】:

  • 哪些方法获得了错误的访问权限?你能把代码贴在它崩溃的地方吗?
  • 对了,retain应该换成strong(retain是pre-ARC)

标签: objective-c exc-bad-access retaincount ivar


【解决方案1】:

如果您愿意,可以使用实例变量(本质上是全局变量)而不是属性。它看起来像这样:

@interface YourClass {
    MyCustomControl *control;
}

【讨论】:

    【解决方案2】:

    应该使用属性,因为属性传达了所有权的概念,这使您的代码更易于理解和维护。

    也许您不愿意让控件成为实例化它的视图控制器的属性,因为它不属于该视图控制器。那么问题就变成了,控制属于什么?如果它属于导航控制器,请考虑将导航控制器子类化并将您的控件添加为导航控制器属性。

    如果控件是 UIView 的子类并且将被添加到视图层次结构中,则不需要将其作为属性保留,因为它将被其父视图保留并在不再位于视图层次结构中时释放。

    如果我的建议对您没有意义,您能否提供有关控件本身的更多信息?

    【讨论】:

    • 控件不一定添加到调用视图层次结构中。控件的目的是分离功能以避免大量的视图控制器。该属性不对视图控制器中的任何其他内容负责,因此没有理由保留它。
    【解决方案3】:

    您可以在自定义控件类中使用static 变量,但前提是同时只有一个MyCustomControl 实例(如弹出框,但即使它也需要强变量)。 代码示例:

    // MyCustomControl.m
    
    static MyCustomControl * _currentInstance = nil;
    
    -(void)showFromView:(UIView *)fromView
    
    { [_currentInstance dismiss];
    
    // show code here ...
    
    _currentInstance = self;
    
    }
    
    - (void)dismiss
    
    { // remove your control
    
    _currentInstance = nil;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 2021-06-09
      • 1970-01-01
      相关资源
      最近更新 更多