从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败

Posted

技术标签:

【中文标题】从 \'(NSNumber) -> NSNumber\' 转换为不相关类型 \'(Any) -> Any\' 总是失败【英文标题】:Cast from '(NSNumber) -> NSNumber' to unrelated type '(Any) -> Any' always fails从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败 【发布时间】:2017-11-23 18:01:25 【问题描述】:

我转换了这个 Objective-C 函数:

- (NSArray *)grt_map:(id (^)(id))block 
    NSMutableArray *newArray = [NSMutableArray array];
    [self enumerateObjectsUsingBlock:^(id item, NSUInteger index, BOOL *stop) 
        id obj = block(item);
        if (obj) 
            [newArray addObject:obj];
        
    ];
    return newArray;

...进入斯威夫特:

public func grt_map(block:((Any) -> Any)) -> NSArray 
    let array = NSMutableArray()
    self.enumerateObjects ( (item:Any, index:Int, stop: UnsafeMutablePointer<ObjCBool>)->Void in
        if (block(item) != nil) 
            array.add(item)
        
    )
    return array;

但我得到一个错误:

从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败

我该如何解决?

【问题讨论】:

你应该使用 Swift 数组,而不是 NSArrayNSMutableArray 另外,您的 Swift 版本与您的 Objective-C 版本的功能不同:您正在丢弃 block 的响应。 从 ObjC 到 Swift 的字面翻译在大多数情况下都很糟糕。如前所述,使用本机 Array 而不是 enumerateObjects 使用 flatMap() 也可以关闭。而且 snake_cased 方法名称无论如何都不酷;-) 但我想知道您在哪一行收到此错误。看起来问题会在您调用grt_map 时出现,而不是在grt_map 内。看起来您正在向它传递 NSNumber 值的闭包。坦率地说,无论如何,我都不鼓励使用Any(或AnyObject)。指定特定类型或使用泛型。但是Any/AnyObject这样的操作有点笨拙。 使用 Swift 数组,您可以通过内置的 mapflatMap 方法免费获得该功能。 【参考方案1】:

如果为 nsarray 做扩展,你应该记住它需要可以转换为 objc 类型的对象。 改变这个:

public func grt_map(block:((Any) -> Any)) -> NSArray

到这里:

public func grt_map(block:((AnyObject?) -> AnyObject? )) -> NSArray

使用 Any,扩展名应该是 Array,而不是 NSArray

更新 像这样测试: array.grt_map(block: (item: AnyObject?) in ...

【讨论】:

我修复了它,但是在 if block :if (block(item as AnyObject) != nil) array.add(item) 有一些通知,带有此警告“比较非可选类型的值'AnyObject' 到 nil 总是返回 true" - 如何修复它 哦,对不起。 id 类型是可以为空的,所以使public func grt_map(block:((AnyObject?) -&gt; AnyObject? )) -&gt; NSArray 谢谢。但是当我测试它时: func test_grt_map() let list : NSArray = [1, 2, 3] var result : NSArray = list; result = list.grt_map(block: (num:NSNumber) in return num ) XCTAssertTrue(list.isEqual(to: result as![Any]));此代码抛出错误“无法将类型 '(NSNumber) -> NSNumber' 的值转换为预期的参数类型 '(Any) -> Any'” @HoangTuan 提供测试代码。不知道你是怎么用的))) 好的,这个函数我用来给 NSArray 添加更多扩展,这是我的类: extension NSArray public func grt_map(block:((AnyObject) -> AnyObject?)) -> NSArray let array = NSMutableArray() self.enumerateObjects ( (item:Any, index:Int, stop: UnsafeMutablePointer)->Void in if (block(item as AnyObject) != nil) array.add(item) ) 返回数组;

以上是关于从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败的主要内容,如果未能解决你的问题,请参考以下文章

从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败

在 Objective-C 中将货币字符串转换为浮点数

从 plist/dictionary 转换为 NSNumber 时出错

Restkit 从 NSNumber 序列化布尔值

NSNumber 到 NSInteger 从 2 到 528839664

如何从匹配 NSNumber 的 NSMutableArray 中删除对象