2014-01-16 109 views
1

我一直在开发一个自定义的UIAlertView类来拥有一个完成块。有一个委托引用自己可以吗?例如:参考自己的代表

PYAreaAlertView.h

@interface PYAreatAlertView : UIAlertView 

@property (nonatomic, copy) CompletionBlock completion; 

- (id)initWithCompletion:(CompletionBlock)completion; 

@end 

PYAreaAlertView.m

@interface PYAreaAlertView() <UIAlertViewDelgate> 

@end 

@implementation PYAreaAlertView 

- (id)initWithCompletion:(CompletionBlock)completion 
{ 
    self = [super init]; 

    if (self) 
    { 
     _completion = completion 

     self.title = @"Add Area" 
     self.message = @""; 
     self.delegate = self // Is this ok?? 
    } 

    return self 
} 

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    NSString *buttonTitle = [alertView buttonTitleAtIndex:buttonIndex]; 

    if ([buttonTitle isEqualToString:@"Done"] && self.completion) 
     self.completion(); 
} 

回答

0

请注意,您还将delegate属性暴露给您的班级的用户,因为PYAreatAlertViewUIAlertView。因此,如果用户提供不同的delegate,则执行完成块的逻辑可能不起作用。

另外,只需谨慎一点:建议UIAlertView不应被分类。

From UIAlertView docs

的UIAlertView中类旨在被原样使用,并且不支持子类。该类的视图层次结构是私有的,不能修改。

在这种情况下,您最好创建自定义UIView并复制警报视图外观。在这里你可以实现委托和/或完成块设计。

编辑:

在理论上,一个代表是一种作用于代,或与另一个对象的协调时该对象遇到在一个程序中的事件的对象。因此,当您将班级的代表设置为self时,您就失败了委派模式的目的。

希望有帮助!

+1

这真是太棒了!非常感谢!。我在很多开放源代码中看到过使用UIAlertView实现块的代码风格。 –

0

这是完全合法的,因为你的类符合<UIAlertViewDelegate>协议。 这也是一个好主意,因为不要将你的代理外包给另一个班级,你可以把它全部留在内部。

但是,与此技术相反的是,它打破了模型 - 视图 - 控制器的风格。处理逻辑的观点(UIView的子类)打破了MVC范式。您可以尝试创建一个名为MyAlertViewDelegate : NSObject <UIAlertViewDelegate>的新类,将其实例化,然后将其指定为您的委托。这通过分离模型和视图来保持您的MVC完好无损。

0

self.delegate = self完全没问题,并且是子类化框架方法时的一个很常见的模式。 delegate几乎总是一个弱引用,所以你没有得到循环引用。

0

将代理设置为自我有一个非常好的解释here.从本质上讲,代理是您想要发送消息的地方,所以如果这是您想要实现的目标,那就完全没问题。