简体   繁体   English

ARC和自动发布对象

[英]ARC and autoreleased object

I need a ViewController to be called modally to show some UIButton and other UIView on top of the current window. 我需要一个ViewController进行模态调用,以在当前窗口的顶部显示一些UIButton和其他UIView。 I want the background to be partially transparent and showing the current window below it - something similar to a UIActionSheet but with a custom design. 我希望背景是部分透明的,并在其下方显示当前窗口-与UIActionSheet类似,但具有自定义设计。 I coded my VC to do the following: 1) during init the VC sets self.view.frame equals to [[UIApplication sharedApplication]keyWindow].frame 2) when show() is called the VC adds self.view on top of [[UIApplication sharedApplication]keyWindow] subViews 3) when an internal button calls the private method release() the VC remove self.view from its superview. 我对VC进行了编码,以执行以下操作:1)在初始化过程中,VC将self.view.frame设置为[[UIApplication sharedApplication] keyWindow] .frame 2)调用show()时,VC在[ [UIApplication sharedApplication] keyWindow]子视图3)内部按钮调用私有方法release()时,VC从其超级视图中删除self.view。 Example with a single release button as follows: 单个释放按钮的示例如下:

@implementation ModalController

- (id)init
{
   self = [super init];
   if (self){
       //set my view frame equal to the keyWindow frame
       self.view.frame = [[UIApplication sharedApplication]keyWindow].frame;
       self.view.backgroundColor = [UIColor colorWithWhite:0.3f alpha:0.5f];

       //create a button to release the current VC with the size of the entire view
       UIButton *releaseMyselfButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
       [releaseMyselfButton setTitle:@"Release" forState:UIControlStateNormal];
       releaseMyselfButton.frame = CGRectMake(0, 0, 90, 20);
       [releaseMyselfButton addTarget:self action:@selector(releaseMyself) forControlEvents:UIControlEventTouchDown];

       //add the button to the view
       [self.view addSubview:releaseMyself];
   }
   return self;
}

- (void) show
{
   //add self.view to the keyWindow to make sure that it will appear on top of everything else
   [[[UIApplication sharedApplication]keyWindow] addSubview:self.view];
}

- (void)releaseMyself
{
    [self.view removeFromSuperview];
}

@end

If I create an instance of ModalController from another VC and I call show() everything goes as expected: 如果我从另一个VC创建ModalController的实例,然后调用show(),一切将按预期进行:

@interface CurrentVC ()
   @property (strong, nonatomic) ModalController *myModalController;
@end

@implementation CurrentVC
   - (void)viewDidLoad
   {
      [super viewDidLoad];
      self.myModalController = [[ModalController alloc]init];
      [self.myModalController show];
   }
@end

To make it work I need to retain the ModalController in a property until release () is called. 为了使其工作,我需要将ModalController保留在一个属性中,直到调用release()。 However I would like to have the same freedom I have with UIActionSheet and simply keep an instance of it in a local variable: 但是,我希望拥有与UIActionSheet相同的自由,只需将其实例保存在局部变量中即可:

@implementation CurrentVC
   - (void)viewDidLoad
   {
      [super viewDidLoad];
      ModalController *myModalController = [[ModalController alloc]init];
      [myModalController show];
   }
@end

If I do this with the current code ARC will release myModalController straight after show() is called and the release button will be pointing to nil. 如果我使用当前代码执行此操作,ARC将在调用show()之后立即释放myModalController,并且释放按钮将指向nil。 How can I make this work without storing the object in a property? 如何在不将对象存储在属性中的情况下完成这项工作? I've identified a work around but I'm not sure it's a good design option: 我已经确定了一种解决方法,但是我不确定这是一个好的设计选择:

@interface ModalController ()
   @property (strong, nonatomic) ModalController *myselfToAutorelease;

@implementation ModalController

- (id)init
{
   self = [super init];
   if (self){
       ... ... ...
       self.myselfToAutorelease = self;
   }
   return self;
}

- (void) show
{
   ... ... ...
}

- (void)releaseMyself
{
    [self.view removeFromSuperview];
    self.myselfToAutorelease = nil;
}

What I've done is making ModalController "self sufficient" - it stores a pointer to itself during init and set it to nil when it's ready to release himself. 我所做的是使ModalController具有“自给自足”的功能-它在初始化期间存储一个指向自身的指针,并在准备释放自己时将其设置为nil。 It works but I have the feeling that this is against the ARC design principles! 它可以工作,但是我感觉这违反了ARC设计原则! Is this approach correct? 这种方法正确吗? If not, how can I handle this differently? 如果没有,我该如何处理?

Thanks in advance for your help. 在此先感谢您的帮助。

Doesn't work like that. 不能那样工作。 You don't keep a reference to self. 你没有提及自我。 In the main view controller you just create your object. 在主视图控制器中,您只需创建您的对象。 If you need it to be around longer keep it in a property in the main view controller , when done, set the property to nil in the main view controller. 如果需要更长的时间,请将其保留在主视图控制器中的一个属性中,完成后,在主视图控制器中将该属性设置为nil。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM