强烈提到"自我"以保持对象存活(暂时):邪恶?

Fre*_*ame 2 objective-c object-lifetime uialertview ios automatic-ref-counting

我正在创建一个包装器UIAlertView(我知道UIAlertController几个已经存在的包装器,它也用于教育目的).

假设它看起来像这样(非常缩短的版本):

@interface MYAlertView : NSObject
-(void)show;
@end

@interface MYAlertView()<UIAlertViewDelegate>
@end

@implementation MYAlertView
-(void)show {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Some title"
                                                        message:@"Some message"
                                                       delegate:self 
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:nil];

    [alertView show]
}

#pragma mark UIAlertViewDelegate implementation

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    //Do something.
}
@end
Run Code Online (Sandbox Code Playgroud)

并且,例如,我像这样使用它:

// USAGE (inside some ViewController)
-(void)showMyAlert {
    dispatch_async(dispatch_get_main_queue(), ^{
        MYAlertView *myAlertView = [[MYAlertView alloc] init];
        [myAlertView show];
    });
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题如下:

  1. [myAlertView show]导致alertView出现.myAlertView被设置为的代表alertView.
  2. 唯一强有力的参考myAlertView:showMyAlert方法中的块内部.完成后,将myAlertView被取消分配.
  3. 当用户单击上的按钮时alertView,alertView调用它的委托方法,但委托(myAlertView)已经解除分配,因此它会导致BAD_ACCESS(委托输入UIAlertView被声明为assign,而不是weak).

我想使其MYAlertView易于使用UIAlertView,因此我不想让用户在某处存储强引用(这很不方便).

因此,myAlertView只要以alertView某种方式显示,我就必须保持活着.问题是除了在内部创建一个强引用MyAlertView,将其分配给self我,当我显示alertView它并将其分配给我时,我无法想到nil它.

像这样(只改变位):

@interface MYAlertView()<UIAlertViewDelegate>
//ADDED:
@property (nonatomic, strong) id strongSelfReference;
@end

@implementation MYAlertView
-(void)show {
    UIAlertView *alertView = [[UIAlertView alloc] init /*shortened*/];
    [alertView show]

    //ADDED:
    self.strongSelfReference = self;
}

#pragma mark UIAlertViewDelegate implementation
//ADDED:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    self.strongSelfReference = nil;
}
@end
Run Code Online (Sandbox Code Playgroud)

它应该工作:当alertView被解雇的那一刻,strongSelfReference将被设置为nil,将没有留下强烈的参考myAlertView,并且它将被解除分配(理论上).

但保持这样的强烈参考self看起来对我来说是邪恶的.有没有更好的办法?

更新:MYAlertView现实中是围绕着一个抽象层,现在已经过时 UIAlertView和新UIAlertController(的iOS 8+),这样子类UIAlertView是不是一种选择.

rob*_*off 9

是的,你的对象应该对自己有很强的参考价值.这样做并不邪恶.

自我引用(或者,通常,任何参考周期)本质上不是邪恶的.邪恶来自于无意中创造一个它永远不会被打破,从而泄漏物体.你不是那样做的.