错误 "NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'"
Error "NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'"
我有以下代码,其中我传递了一个类型为 "Hello|r World|g"
的字符串,下面的函数将其转换为 attributedString
且 "Hello"
为 red
颜色和 "World"
是 green
颜色。我在传递数组中的每个字符串时使用了它。该函数只为文本着色,直到它找到一个特殊字符,如结束期间的条件所示,然后为文本着色。
代码:
func formatAttributedString(string:String)->NSMutableAttributedString {
var strCopy=string as NSString
var color:UIColor=UIColor()
var attributedString:NSMutableAttributedString!
for var i:Int=0;i<strCopy.length-2;i++ {
if (string[i] == "|") {
println("|")
var j:Int
if string[i+1] == "r" {
color=UIColor(red: 249, green: 39, blue: 14, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|r", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("r")
}
else if string[i+1] == "v" {
color=UIColor(red: 161, green: 153, blue: 249, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|v", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("v")
}
else if string[i+1] == "y" {
color=UIColor(red: 235, green: 223, blue: 145, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|y", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("y")
}
else if string[i+1] == "g" {
color=UIColor(red: 174, green: 227, blue: 79, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|y", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("g")
}
else if string[i+1] == "b" {
color=UIColor(red: 107, green: 224, blue: 240, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|b", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("b")
}
for j=i; j>=0;j-- {
if string[j] == " " || string[j] == "/" || string[j] == "." || string[j] == "\"" || string[j] == "\n" || string[j] == "<" || string[j] == "\t" || string[j] == "("{
println("/")
break
}
}
attributedString=NSMutableAttributedString(string: strCopy)
attributedString.addAttribute("NSForegroundColorAttributeName", value: color, range: NSMakeRange(j, i-j))
}
}
我收到以下错误:
'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'
正如我添加的 println
s , |
和 r
得到打印。
请帮助,提前致谢。
这不是 this question 的副本,因为正在打印 |
和 r
。
我猜错误发生在这一行:
attributedString.addAttribute("NSForegroundColorAttributeName", value: color, range: NSMakeRange(j, i-j))
让我们看看您的字符串 "Hello|r World|g" - 它有 15 个字符长。
让我们看看外部 for 找到第二个“|”时的迭代。
strCopy 现在是 "Hello World|g" - 13 个字符长,i = 11。
程序找到一个“|”然后是 "r" 并将 strCopy 更改为 "Hello World|g" - 11 个字符长,但 i = 11.
在内部 for 中的 "scan" 之后,我们最终得到 j = 7。
在这一行中,您从 "Hello World":
创建了一个可变字符串
attributedString=NSMutableAttributedString(string: strCopy)
它与 strCopy 本身一样,长度等于 11。
现在,在最后一行中,您为 NSRangeMake(7, 4) 范围内的字符设置属性,这意味着它应用的最后一个字符将在索引 11 处。此字符串中的最后一个索引是 10,即为什么会崩溃。
编辑:
为避免此崩溃,您应该在每行 stringByReplacingOccurencesOfString.
之后添加 "i--;"
你还应该做的另一件事(不会导致崩溃,但仍然会导致故障)是更改内部 for 以便循环行如下所示:
for j = i + (string.length - strCopy.length); j>=0; j-- {
您的算法似乎依赖于 i
指向最后处理的字符。每当你遇到 |?模式,您最终用“”替换了两个特殊字符,有效地将复制字符串大小减少了 2.
解决问题的最简单方法是在每次调用 strCopy.stringByReplacingOccurrencesOfString...
后添加 i=i-2
。
这使 i
函数末尾的代码保持正确。
理想情况下,您可能需要考虑重组功能以将项目从原始版本移动到新版本,同时添加颜色等。这将节省所有向后搜索。
我已经尝试使用 Swift 的匿名元组和更高阶函数的另一个实现来满足您的函数签名。我这样做是为了自己练习,最后认为最好分享一下。
func formatAttributedString(string: String) -> NSMutableAttributedString {
// create a mapping between the attribute token and the corresponding UIColor
let colors = [
"|r": UIColor(red: 249/255, green: 39/255, blue: 14/255, alpha: 1.0),
"|v": UIColor(red: 161/255, green: 153/255, blue: 249/255, alpha: 1.0),
"|y": UIColor(red: 235/255, green: 223/255, blue: 145/255, alpha: 1.0),
"|g": UIColor(red: 174/255, green: 227/255, blue: 79/255, alpha: 1.0),
"|b": UIColor(red: 107/255, green: 224/255, blue: 240/255, alpha: 1.0)]
// split argument into an array of (String, UIColor) tuples
// default the array to the entire argument string with a black color
var substrings = [(string, UIColor.blackColor())]
for (token, color) in colors {
substrings = substrings.flatMap {
var substrings = [=10=].0.componentsSeparatedByString(token)
let tail = (substrings.removeLast(), [=10=].1) // tuple for trailing string at old color
var result = substrings.map{([=10=], color)} // array of tuples for strings at new color
result.append(tail)
return result
}
}
// because we default the original string to black, there may be an empty string tuple at the end
substrings = substrings.filter{(string, _) in return !string.isEmpty}
// convert array of (String, UIColor) tuples into a single attributed string
var result = reduce(substrings, NSMutableAttributedString(string: "")) {
var string = NSAttributedString(string: .0, attributes: [NSForegroundColorAttributeName: .1])
[=10=].appendAttributedString(string)
return [=10=]
}
return result
}
我有以下代码,其中我传递了一个类型为 "Hello|r World|g"
的字符串,下面的函数将其转换为 attributedString
且 "Hello"
为 red
颜色和 "World"
是 green
颜色。我在传递数组中的每个字符串时使用了它。该函数只为文本着色,直到它找到一个特殊字符,如结束期间的条件所示,然后为文本着色。
代码:
func formatAttributedString(string:String)->NSMutableAttributedString {
var strCopy=string as NSString
var color:UIColor=UIColor()
var attributedString:NSMutableAttributedString!
for var i:Int=0;i<strCopy.length-2;i++ {
if (string[i] == "|") {
println("|")
var j:Int
if string[i+1] == "r" {
color=UIColor(red: 249, green: 39, blue: 14, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|r", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("r")
}
else if string[i+1] == "v" {
color=UIColor(red: 161, green: 153, blue: 249, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|v", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("v")
}
else if string[i+1] == "y" {
color=UIColor(red: 235, green: 223, blue: 145, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|y", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("y")
}
else if string[i+1] == "g" {
color=UIColor(red: 174, green: 227, blue: 79, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|y", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("g")
}
else if string[i+1] == "b" {
color=UIColor(red: 107, green: 224, blue: 240, alpha: 1)
strCopy = strCopy.stringByReplacingOccurrencesOfString("|b", withString: "", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, i + 2))
println("b")
}
for j=i; j>=0;j-- {
if string[j] == " " || string[j] == "/" || string[j] == "." || string[j] == "\"" || string[j] == "\n" || string[j] == "<" || string[j] == "\t" || string[j] == "("{
println("/")
break
}
}
attributedString=NSMutableAttributedString(string: strCopy)
attributedString.addAttribute("NSForegroundColorAttributeName", value: color, range: NSMakeRange(j, i-j))
}
}
我收到以下错误:
'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'
正如我添加的 println
s , |
和 r
得到打印。
请帮助,提前致谢。
这不是 this question 的副本,因为正在打印 |
和 r
。
我猜错误发生在这一行:
attributedString.addAttribute("NSForegroundColorAttributeName", value: color, range: NSMakeRange(j, i-j))
让我们看看您的字符串 "Hello|r World|g" - 它有 15 个字符长。 让我们看看外部 for 找到第二个“|”时的迭代。 strCopy 现在是 "Hello World|g" - 13 个字符长,i = 11。 程序找到一个“|”然后是 "r" 并将 strCopy 更改为 "Hello World|g" - 11 个字符长,但 i = 11.
在内部 for 中的 "scan" 之后,我们最终得到 j = 7。
在这一行中,您从 "Hello World":
创建了一个可变字符串attributedString=NSMutableAttributedString(string: strCopy)
它与 strCopy 本身一样,长度等于 11。
现在,在最后一行中,您为 NSRangeMake(7, 4) 范围内的字符设置属性,这意味着它应用的最后一个字符将在索引 11 处。此字符串中的最后一个索引是 10,即为什么会崩溃。
编辑: 为避免此崩溃,您应该在每行 stringByReplacingOccurencesOfString.
之后添加 "i--;"你还应该做的另一件事(不会导致崩溃,但仍然会导致故障)是更改内部 for 以便循环行如下所示:
for j = i + (string.length - strCopy.length); j>=0; j-- {
您的算法似乎依赖于 i
指向最后处理的字符。每当你遇到 |?模式,您最终用“”替换了两个特殊字符,有效地将复制字符串大小减少了 2.
解决问题的最简单方法是在每次调用 strCopy.stringByReplacingOccurrencesOfString...
后添加 i=i-2
。
这使 i
函数末尾的代码保持正确。
理想情况下,您可能需要考虑重组功能以将项目从原始版本移动到新版本,同时添加颜色等。这将节省所有向后搜索。
我已经尝试使用 Swift 的匿名元组和更高阶函数的另一个实现来满足您的函数签名。我这样做是为了自己练习,最后认为最好分享一下。
func formatAttributedString(string: String) -> NSMutableAttributedString {
// create a mapping between the attribute token and the corresponding UIColor
let colors = [
"|r": UIColor(red: 249/255, green: 39/255, blue: 14/255, alpha: 1.0),
"|v": UIColor(red: 161/255, green: 153/255, blue: 249/255, alpha: 1.0),
"|y": UIColor(red: 235/255, green: 223/255, blue: 145/255, alpha: 1.0),
"|g": UIColor(red: 174/255, green: 227/255, blue: 79/255, alpha: 1.0),
"|b": UIColor(red: 107/255, green: 224/255, blue: 240/255, alpha: 1.0)]
// split argument into an array of (String, UIColor) tuples
// default the array to the entire argument string with a black color
var substrings = [(string, UIColor.blackColor())]
for (token, color) in colors {
substrings = substrings.flatMap {
var substrings = [=10=].0.componentsSeparatedByString(token)
let tail = (substrings.removeLast(), [=10=].1) // tuple for trailing string at old color
var result = substrings.map{([=10=], color)} // array of tuples for strings at new color
result.append(tail)
return result
}
}
// because we default the original string to black, there may be an empty string tuple at the end
substrings = substrings.filter{(string, _) in return !string.isEmpty}
// convert array of (String, UIColor) tuples into a single attributed string
var result = reduce(substrings, NSMutableAttributedString(string: "")) {
var string = NSAttributedString(string: .0, attributes: [NSForegroundColorAttributeName: .1])
[=10=].appendAttributedString(string)
return [=10=]
}
return result
}