我的项目中有一个单独的WarningManager类,如下所示
WarningManager.h文件
+ (WarningManager *)getInstance;
- (void) createAndPushWarning:(id<UIAlertViewDelegate>)actionDelegate isLocalisedStrings:(BOOL)localized text:(NSString *)text cancel:(NSString *)cancel buttons:(NSString*)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
WarningManager.m文件
static WarningManager *instance = nil;
+ (WarningManager *) getInstance {
if (!instance) {
instance = [[self alloc] init];
}
return instance;
}
- (void) createAndPushWarning:(id<UIAlertViewDelegate>)actionDelegate isLocalisedStrings:(BOOL)localized text:(NSString *)text cancel:(NSString *)cancel buttons:(NSString*)firstObj, ... {
va_list argumentList;
va_start(argumentList, firstObj);
NSMutableArray *buttonArray = [NSMutableArray array];
if(firstObj){
if(!localized){
[buttonArray addObject:NSLocalizedString(firstObj, @"")];
} else {
[buttonArray addObject:firstObj];
}
id eachObject;
while ((eachObject = va_arg(argumentList, id))){
if(!localized){
[buttonArray addObject: NSLocalizedString(eachObject, @"")];
}else{
[buttonArray addObject: eachObject];
}
}
}
if (!localized) {
if(text){
text = NSLocalizedString(text, @"");
}
if(cancel){
cancel = NSLocalizedString(cancel, @"");
}
}
va_end(argumentList);
LogW(@"Warning : %@",text);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"My App Name", @"") message:text delegate:actionDelegate cancelButtonTitle:cancel otherButtonTitles:nil];
for (NSString *button in buttonArray) {
[alertView addButtonWithTitle:button];
}
[alertView show];
}
当一个目标--C类文件调用如下
时,上面的代码很有效[[WarningManager getInstance] createAndPushWarning:self isLocalisedStrings:NO text:@"Text want to display" cancel:nil buttons:@"Button 1", @"Button 2", nil];
现在我正在创建swift类,我想在其中使用相同的警告管理器,但是在swift中改变了可变参数函数语法,所以我在WarningManager类中通过替换variadic参数添加了另一个方法。
WarningManager.h文件
- (void) createAndPushWarning:(id<UIAlertViewDelegate>)actionDelegate isLocalisedStrings:(BOOL)localized text:(NSString *)text cancel:(NSString *)cancel agruments:(va_list)buttons
WarningManager.M文件
- (void) createAndPushWarning:(id<UIAlertViewDelegate>)actionDelegate isLocalisedStrings:(BOOL)localized text:(NSString *)text cancel:(NSString *)cancel agruments:(va_list)buttons {
[self createAndPushWarning:actionDelegate isLocalisedStrings:localized text:text cancel:cancel buttons:(__bridge NSString *)(buttons), nil];
}
要从swift类中调用它,我在WarningManager + ArgumentList.swift文件中创建了一个对WarningManager类的扩展,如下所示
extension WarningManager {
class func WarningWrapper(actionDelegate: UIAlertViewDelegate, isLocalizedString: Bool, text:String, cancel: String, _ args: CVarArg...) {
withVaList(args) { _ in WarningManager.getInstance().createAndPushWarning(actionDelegate, isLocalisedStrings: isLocalizedString, text: text, cancel: cancel, agruments: getVaList(args)) }
}
}
从swift类调用我的扩展方法
WarningManager.WarningWrapper(actionDelegate: self, isLocalizedString: false, text: "Message to Display", cancel: "OK", "")
因此,当我从swift类调用此扩展时,我的访问错误
但我更改了我的WarningManager.m文件,它会显示警告。
- (void) createAndPushWarning:(id<UIAlertViewDelegate>)actionDelegate isLocalisedStrings:(BOOL)localized text:(NSString *)text cancel:(NSString *)cancel agruments:(va_list)buttons {
[self createAndPushWarning:actionDelegate isLocalisedStrings:localized text:text cancel:cancel buttons:nil];
}
在某些地方,我在发送参数时犯了错误,我不知道如何解决这个问题。
感谢任何建议和想法,感谢提前阅读此问题的人。
答案 0 :(得分:1)
您无法传递需要实际参数列表的va_list,即使它们是可变参数。将va_list视为数组。您无法传递需要参数列表的数组,并期望将每个数组项视为单个参数。整个数组作为单个第一个参数传递。
在一个理想的世界中,你会得到一个错误(在纯粹的Swift中),但是C的可变参数列表不包含足够的类型信息以便能够检测到这个错误。
您需要反转代码:将大部分代码放入va_list-taking版本(使用&#34;参数:&#34;参数),然后从可变版本调用该函数,该版本只调用va_start,调用va_list版本,然后调用va_end。