从 '(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 数组,而不是NSArray
和 NSMutableArray
。
另外,您的 Swift 版本与您的 Objective-C 版本的功能不同:您正在丢弃 block
的响应。
从 ObjC 到 Swift 的字面翻译在大多数情况下都很糟糕。如前所述,使用本机 Array
而不是 enumerateObjects
使用 flatMap()
也可以关闭。而且 snake_cased 方法名称无论如何都不酷;-)
但我想知道您在哪一行收到此错误。看起来问题会在您调用grt_map
时出现,而不是在grt_map
内。看起来您正在向它传递 NSNumber
值的闭包。坦率地说,无论如何,我都不鼓励使用Any
(或AnyObject
)。指定特定类型或使用泛型。但是Any
/AnyObject
这样的操作有点笨拙。
使用 Swift 数组,您可以通过内置的 map
或 flatMap
方法免费获得该功能。
【参考方案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?) -> AnyObject? )) -> 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以上是关于从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败的主要内容,如果未能解决你的问题,请参考以下文章
从 '(NSNumber) -> NSNumber' 转换为不相关类型 '(Any) -> Any' 总是失败
从 plist/dictionary 转换为 NSNumber 时出错