【问题标题】:Why is the return value of String.addingPercentEncoding() optional?为什么 String.addingPercentEncoding() 的返回值是可选的?
【发布时间】:2016-02-07 03:16:06
【问题描述】:

String 百分比转义方法的签名是:

func addingPercentEncoding(withAllowedCharacters: CharacterSet)
    -> String?

(这是 Swift 2 中的 stringByAddingPercentEncodingWithAllowedCharacters。)

为什么这个方法返回一个可选项?

文档说“如果无法进行转换”,该方法会返回 nil,但不清楚在什么情况下转义转换可能会失败:

  • 使用 UTF-8 对字符进行转义,这是一种完整的 Unicode 编码。任何有效的 Unicode 字符都可以使用 UTF-8 进行编码,因此可以转义。

  • 我认为该方法可能对允许的字符集和用于转义的字符之间的不良交互进行了某种健全性检查,但事实并非如此:无论允许的字符集是否chars 包含“%”,如果允许的字符集为空也成功。

就目前而言,非可选返回值似乎强制进行无意义的错误检查。

【问题讨论】:

    标签: swift cocoa unicode utf-8 url-encoding


    【解决方案1】:

    我就此向 Apple 提交了错误报告,并得到了回复 — 得到了非常有帮助的回复,不少于!

    结果(令我惊讶的是)可以成功创建包含不成对 UTF-16 surrogate chars 形式的无效 Unicode 的 Swift 字符串。这样的字符串会导致 UTF-8 编码失败。下面是一些说明这种行为的代码:

    // Succeeds (wat?!):
    let str = String(
        bytes: [0xD8, 0x00] as [UInt8],
        encoding: .utf16BigEndian)!
    
    // Returns nil:
    str.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
    

    【讨论】:

    • 这个答案中的str 看起来像“�”
    【解决方案2】:

    根据 Paul Cantrell 的回答,一个小的演示表明,尽管 String 和 NSString 在编码方面是不同的野兽,但在 Objective-C 中同样的方法也可能返回 null:

    uint8_t bytes[2] = { 0xD8, 0x00 };
    NSString *string = [[NSString alloc] initWithBytes:bytes length:2 encoding:NSUTF16BigEndianStringEncoding];
    // \ud800
    NSLog(@"%@", string);
    
    NSString *escapedString = [string stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLHostAllowedCharacterSet];
    // (null)
    NSLog(@"%@", escapedString);
    

    为了好玩,https://r12a.github.io/app-conversion/ 将百分比转义为:

    Error%20in%20convertUTF162Char%3A%20low%20surrogate%20expected%2C%20b%3D0%21%00

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 2012-02-12
      • 2017-10-04
      • 1970-01-01
      • 2020-10-31
      • 2020-05-17
      • 2011-08-24
      相关资源
      最近更新 更多