(Рабочее решение, основанное на ответах, приведено в конце этого поста.)
Я подумал, что это будет аккуратный способ обрабатывать обратные вызовы, которые должны обрабатываться определенным представлением предупреждений,поэтому у меня нет единого метода делегата, отфильтровывающего все нажатия кнопок оповещения.Вот код:
#import "LSAlertView.h"
@implementation LSAlertView
- (id) initWithTitle:(NSString *)title
message:(NSString *)message
actionBlocks:(NSArray*)_actionBlocks
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ...
{
self = [super initWithTitle:title
message:message
delegate:self
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:otherButtonTitles,nil];
if (self) {
self.cancelButtonIndex = 0;
actionBlocks = [_actionBlocks retain];
[self show];
}
return self;
}
- (void) dealloc {
[actionBlocks release];
[super dealloc];
}
- (void) alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
void (^action)(void) = [actionBlocks objectAtIndex:buttonIndex];
action();
}
@end
Это прекрасно работает для двух кнопок, настроенных так:
- (void) restartSearches {
NSArray *actionBlocks = [NSArray arrayWithObjects:
^{NSLog(@"Cancel Button Selected");},
^{NSLog(@"Delete Button Selected");},
nil];
alertDeletingSearches = [[LSAlertView alloc]
initWithTitle:@"You Are About To Delete Your Current Searches"
message:@"Select Delete to Continue"
actionBlocks:actionBlocks
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Delete", nil];
[alertDeletingSearches release];
}
Но как только я добавлю несколько полезных вызовов в один из блоков, напримерэто
- (void) restartSearches {
NSArray *actionBlocks = [NSArray arrayWithObjects:
^{NSLog(@"Cancel Button Selected");},
^{
[mapController.theMap removeAnnotations:mapController.theMap.annotations];
[dataInterface deleteDB];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"changeToFavorites"
object:nil];
NSLog(@"Delete Button Selected");
},
nil];
alertDeletingSearches = [[LSAlertView alloc]
initWithTitle:@"You Are About To Delete Your Current Searches"
message:@"Select Delete to Continue" actionBlocks:actionBlocks
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Delete", nil];
[alertDeletingSearches release];
}
зависает, и я получаю ошибку EXC_BAD_ACCESS.
Я делаю что-то в корне неправильно или в моей логике есть небольшая ошибка?
ОБНОВЛЕНИЕ
Решил проблему с вариадностью, используя предложенное Фирозом предложение ниже.(Следует примерам, приведенным на Numbergrinder )
- (id) initWithTitle:(NSString *)title message:(NSString *)message actionBlocks:(NSArray*)_actionBlocks cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... {
self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil];
if (self) {
va_list args;
va_start(args, otherButtonTitles);
NSString* buttonTitle;
while ((buttonTitle = va_arg(args, NSString *))) {
[super addButtonWithTitle:buttonTitle];
}
self.cancelButtonIndex = 0;
actionBlocks = [_actionBlocks retain];
[self show];
}
return self;
}
Вот файл заголовка:
@interface LSAlertView : UIAlertView <UIAlertViewDelegate> {
NSArray *actionBlocks;
}
- (id) initWithTitle:(NSString *)title message:(NSString *)message actionBlocks:(NSArray*)_actionBlocks cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...;
@end