1

I been developing a custom UIAlertView class to have an completion block. Is it ok to have a delegate reference to itself?? For example:

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();
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Reza Safari
  • 377
  • 2
  • 4
  • 6

3 Answers3

0

This is perfectly legal because your class conforms to the <UIAlertViewDelegate> protocol. This is also a good idea because instead of out-sourcing your delegate to another class, you can keep all of it in house.

One contrary to this technique though, is that fact that it breaks the Model-View-Controller style. Having your view (subclasses of UIView) dealing with logic breaks the MVC paradigm. You might try creating a new class called MyAlertViewDelegate : NSObject <UIAlertViewDelegate>, instantiating it, then assigning it as your delegate. This keeps your MVC intact by separating the Model and the View.

Brian Tracy
  • 6,801
  • 2
  • 33
  • 48
0

self.delegate = self is completely ok and a pretty common pattern when subclassing framework methods. delegate is almost always a weak reference so you're not getting a circular reference.

Juri Pakaste
  • 1,402
  • 10
  • 15
0

Beware, that you are also exposing the delegate property to the user of your class, since PYAreatAlertView is a UIAlertView. So your logic of executing a completion block may not work in case user provides different delegate.

Also, just a word of caution: It is recommended that UIAlertView should not be subclassed.

From UIAlertView docs,

The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified.

In such scenarios, you are better off creating a custom UIView and replicating the alert view appearance. Here you can implement the delegation and/or completion block design.

EDIT:

In theory, a delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program. So when you set the delegate of your class as self you defeat the purpose of delegation pattern.

Hope that helps!

Amar
  • 13,202
  • 7
  • 53
  • 71
  • 1
    This is brilliant!!. Thank you so much!. I have seen this kind of code style in lot of the open sources for having blocks implemented with UIAlertView. – Reza Safari Jan 16 '14 at 05:52