Реализация метода делегата UIAlertView в категории

Я пытаюсь реализовать категорию viewcontroller, которая обрабатывает uialertview. Необходимо реализовать -(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex и не портите, если viewcontroller также должен показывать представление с предупреждением. Для этого я назначил делегат uialertview фиктивным объектом в категории вместо self. Но мое приложение вылетает с exc_bad_access когда нажата одна из кнопок в alertview. В чем проблема с кодом ниже?

//Dummy handler .h

@interface dummyAlertViewHandler : NSObject <UIAlertViewDelegate>

@property (nonatomic, weak) id delegate;

//.m
-(id) initWithVC:(id) dlg
{
    self = [super init];
    if (self != nil)
    {
        self.delegate = dlg;
    }
    return self;
}

-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1)
    {
        [self mainMenuSegue]; //There is no problem with the method
    }
}

//Category .h
#define ALERT_VIEW_DUMMY_DELEGATE_KEY "dummy"
@property (nonatomic, strong) id dummyAlertViewDelegate;

//Category .m
@dynamic dummyAlertViewDelegate;

- (void)setDummyAlertViewDelegate:(id)aObject
{
    objc_setAssociatedObject(self, ALERT_VIEW_DUMMY_DELEGATE_KEY, aObject, OBJC_ASSOCIATION_ASSIGN);
}

- (id)dummyAlertViewDelegate
{
    id del = objc_getAssociatedObject(self, ALERT_VIEW_DUMMY_DELEGATE_KEY);

    if (del == nil)
    {
        del = [[dummyAlertViewHandler alloc] initWithVC:self];
        self.dummyAlertViewDelegate = del;
    }

    return del;
}

-(void) mainMenuSegueWithConfirmation
{
    UIAlertView *ruSure = [[UIAlertView alloc] initWithTitle:@"Confirm leave" 
message:@"Are you sure you want to leave this game?" 
delegate:self.dummyAlertViewDelegate 
cancelButtonTitle:@"No" 
otherButtonTitles:@"Yes", nil];

    [ruSure show];
}

1 ответ

Решение

Ваша проблема в этой строке:

objc_setAssociatedObject(self, ALERT_VIEW_DUMMY_DELEGATE_KEY, aObject, OBJC_ASSOCIATION_ASSIGN);

В частности, OBJC_ASSOCIATION_ASSIGN приводит к тому, что связанный объект не сохраняется. Чтобы ваш дизайн работал, вам нужно изменить это на OBJC_ASSOCIATION_RETAIN, вот так:

objc_setAssociatedObject(self, ALERT_VIEW_DUMMY_DELEGATE_KEY, aObject, OBJC_ASSOCIATION_RETAIN);
Другие вопросы по тегам