gpt4 book ai didi

objective-c - 数组中的 Objective-C block 传递给 UIAlertView 的子类

转载 作者:搜寻专家 更新时间:2023-10-30 19:44:51 26 4
gpt4 key购买 nike

(本文末尾提供了基于回复的可行解决方案。)

我认为这是一种处理特定警报 View 需要处理的回调的简洁方法,因此我没有一个委托(delegate)方法来过滤所有警报按钮的按下。这是代码:

#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];
}

但是一旦我在其中一个 block 中添加一些有用的调用,就像这样

- (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 错误。

我是不是做错了什么,或者我的逻辑有什么小错误?

更新

使用下面 Firoze 的建议处理可变参数问题。 (遵循 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

最佳答案

所以我看到了几个问题。

一个是您需要在将这些 block 放入数组时复制它们。这些 block 是在堆栈上创建的。如果你想将它们传递给你的警报 View 并且你希望警报 View 保留它们供以后使用,你需要先将它们复制到堆中。

所以这样的事情应该可行:

NSArray *actionBlocks = [NSArray arrayWithObjects:
[[^{NSLog(@"Cancel Button Selected");} copy] autorelease],
[[^{
[mapController.theMap removeAnnotations:mapController.theMap.annotations];
[dataInterface deleteDB];
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeToFavorites" object:nil];
NSLog(@"Delete Button Selected");
} copy] autorelease]
, nil];

请注意每个 block 文字周围的 [^someBlock copy]。这应该可以解决一个问题。

另一个我不知道答案的问题是,这是一个可变参数方法(采用可变数量的参数)。我不知道在可变参数方法中有什么方法可以转身并调用另一个可变参数方法(UIAlertView 初始值设定项),除非您有第二种方法的变体,它采用 va_list。这与我们在 C 中遇到的问题相同,据我所知在 Objective C 中继承。

我认为你还没有遇到那个问题,因为你还没有为此尝试足够多的按钮。

编辑

进一步考虑这个问题,我想您可以通过遍历可变参数然后为每个可变参数调用 [self addButtonWithTitle:arg] 来解决第二个问题。

关于objective-c - 数组中的 Objective-C block 传递给 UIAlertView 的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8291732/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com