无法将 Float 类型的值转换为预期的参数类型 NSNumber

Posted

技术标签:

【中文标题】无法将 Float 类型的值转换为预期的参数类型 NSNumber【英文标题】:Cannot convert value of type Float to expected argument type NSNumber 【发布时间】:2017-07-14 06:54:16 【问题描述】:

我正在从 swift 类调用目标 c 中的一个方法。我的目标 c 方法期望 NSNumber 格式的数字。我没有在 swift 中定义数字类型,但我仍然收到以下消息。有没有办法解决这个问题?

- (void)getPercentageMatch:(NSString *)answer listOfAnswers:(NSArray *)validAnswers completionBlock:(void(^)(BOOL isSuccess, NSNumber *percent))completionBlock 
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setValue:answer forKey:@"myanswer"];
[params setValue:validAnswers forKey:@"answers"];
NSMutableURLRequest *req = [AuthorizationHandler createAuthReq:@"POST" path:@"validateAnswer" params:params];

AFJSONRequestOperation *op = [[AFJSONRequestOperation alloc] initWithRequest:req];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) 
    NSDictionary *responseheaders = (NSDictionary *)responseObject;
    if (completionBlock) 
        completionBlock(true, [responseheaders valueForKey:@"percentage"]);
    

failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    if (completionBlock) 
        completionBlock(false, 0);
    
];
[op start];
return;

我还强制完成块类型转换

as! completionBlock(Bool, NSNumber)

但这不起作用。

我是 swift 新手,任何教程/指针将不胜感激 :)

编辑 1:

当我修改完成块时

let completionBlock =  (isSuccess, percent) in
        print("-------", isSuccess, percent)
    
    MTRestkitManager.instance().getPercentageMatch(_:text, listOfAnswers:validAnswers, completionBlock:completionBlock)

我没有收到任何错误。但是,如果我再次添加一个轻微的修改,我会得到一个错误。

为什么行为会改变?

编辑 2: 按照科林的解决方案,做了如下改动

    @IBAction func submitButtonTapped(_ sender: Any) 
    answerTextView.resignFirstResponder()
    if answerTextView.textColor == UIColor.lightGray 
        ZUtility.showError(NSLocalizedString("Please enter answer before submitting", comment: ""))
        return;
    
    if answerTextView.text.isEmpty 
        ZUtility.showError(NSLocalizedString("Please enter answer before submitting", comment: ""))
        setPlaceholderText()
        return;
    
    let text = answerTextView.text as String
    let completionBlock =  (isSuccess, percent:NSNumber) -> (Void) in
        self.handleAnswer(isSuccess: isSuccess, percent: Float(percent))
    
    MTRestkitManager.instance().getPercentageMatch(_:text, listOfAnswers:validAnswers, completionBlock:completionBlock)

在最后一行我收到一个错误:无法将类型 '(Bool, NSNumber) -> (Void)' 的值转换为预期的参数类型 '((Bool, NSNumber?) -> (Void)!'

【问题讨论】:

发布您的快速代码而不是图像.. 这有什么不同? 看这个...meta.***.com/a/285557/1825618 明白了。谢谢 :) 让我修改一下。 【参考方案1】:

显然,Float 是从selfhandleAnsewer() 函数推断出来的。您应该手动在 completionBlock 中定义正确的类型:

let completionBlock =  (isSuccess, percent: NSNumber?) in
    self.handleAnsewer(isSuccess: isSuccess, percent: percent.floatValue ?? 0)

请记住,您不能在 Swift 中自动进行类型转换,您应该调用显式初始化器,例如 NSNumber(value: myFloat)Int(percent

附:我打赌你来自 python :)

【讨论】:

谢谢你的回答,科林。我修改了我的代码,它编译但在运行时失败,并在运行时出现消息 EXC_BAD_INSTRUCTION:MTReskitManager.instance().getPercentageMatch(_:text, listOfAnswers:validAnswers,completionBlock:completionBlock as! (Bool, NSNumber?) -> Void) 似乎Float(percent) 返回可选值。我更新了答案。 感谢您的更新。我仍然面临编辑 2 中给出的问题。知道为什么预期的参数类型 NSNumber 是可选的吗?我相信,在objective-c中没有这样的概念。 我将完成块修改为 (isSuccess, percent:NSNumber!) 并且成功了!感谢您的提示。但我仍然想知道它是如何工作的。我将百分比设为必填,但objective-c 是可选的。 getPercentageMatch 函数需要(Bool, NSNumber?) 而不是(Bool, NSNumber)。查看更新。

以上是关于无法将 Float 类型的值转换为预期的参数类型 NSNumber的主要内容,如果未能解决你的问题,请参考以下文章

无法将“字符串”类型的值转换为预期的参数类型 [任何]

Swift:无法将“NSDate”类型的值转换为预期的参数类型“NSDateComponents”

无法将“()”类型的值转换为预期的参数类型“(() -> Void)?”在 swiftui

无法将类型 '(Any) -> ()' 的值转换为预期的参数类型 '(_) -> _'

iOS-无法将“字符串”类型的值转换为预期的参数类型“数据”

错误:无法将类型“(_)->()”的值转换为预期的参数类型“(()-> Void)?”