jjzjj

objective-c - NSString 和 Swift.String 上的 replaceCharactersInRange 之间有区别吗

coder 2023-09-16 原文

我正在为 UITextField 编写一个验证器,我得到了一个现有字符串、替换字符串和一个进行替换的 NSRange。我有两个版本的代码来获取新的候选字符串:

一个。显式使用 NSString

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let existingString: NSString = textField.text ?? ""
    let candidateString =  existingString.stringByReplacingCharactersInRange(range, withString: string)
    //do validation on candidateString here
    return true
}

生成 Range<String.Int>并在 Swift String 的 stringByReplacingCharactersInRange 上使用它

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let existingString = textField.text ?? ""
    let swiftRange = advance(existingString.startIndex, range.length)..<advance(existingString.startIndex, range.length) // I hate this.
    let candidateString = existingString.stringByReplacingCharactersInRange(swiftRange, withString: string)

因此,撇开生成 Swift 范围的代码不可读这一事实不谈……这两种方法在执行上是否有所不同。具体来说,Swift 是否有更好的(可能更懂 unicode)版本的 stringByReplacingCharactersInRange这是我通过避免转换为 NSString 得到的吗?

最佳答案

NSString

NSRange 等同于 String.UTF16.IndexRange(又名 String .UTF16索引).

正确的方法(没有 NSString)是:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let existingString = textField.text ?? ""

    // convert `NSRange` to `Range<String.Index>`
    let start = String.UTF16Index(range.location)
    let end = start.advancedBy(range.length)
    let swiftRange = start.samePositionIn(string)! ..< end.samePositionIn(string)!

    let candidateString = existingString.stringByReplacingCharactersInRange(swiftRange, withString: string)

    // Do validation...

    return true
}

你可以扩展NSRange:

extension NSRange {
    func toStringRangeIn(string: String) -> Range<String.Index>? {
        let start = String.UTF16Index(self.location)
        let end = start.advancedBy(self.length)
        if let start = start.samePositionIn(string), end = end.samePositionIn(string) {
            return start ..< end
        }
        return nil
    }
}

var str  = "?Hello ???"
let range = NSMakeRange(8, 4)
str.stringByReplacingCharactersInRange(range.toStringRangeIn(str)!, withString: "FOO") // -> "?Hello FOO?"
(str as NSString).stringByReplacingCharactersInRange(range, withString: "FOO")  // -> "?Hello FOO?"

有了这个,您可以:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let existingString = textField.text ?? ""
    let candidateString = existingString.stringByReplacingCharactersInRange(
        range.toStringRangeIn(existingString)!,
        withString: string
    )

    // Do validation...

    return true
}

关于objective-c - NSString 和 Swift.String 上的 replaceCharactersInRange 之间有区别吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31695892/

有关objective-c - NSString 和 Swift.String 上的 replaceCharactersInRange 之间有区别吗的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  4. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  5. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  6. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  7. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  8. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  9. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  10. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

随机推荐