超过最大文本(“")连接长度 - SwiftUI - [英] Exceeding max Text("") concatenation length - SwiftUI -
问题描述
参考 Asperi 发布的答案 (https://stackoverflow.com/users/12299030/asperi)关于问题:在 SwiftUI 中突出显示文本的特定部分一个>
With reference to the answer posted by Asperi (https://stackoverflow.com/users/12299030/asperi) on Question: Highlight a specific part of the text in SwiftUI
我发现他的回答非常有用,但是,当我的 String 输入超过 32k 个字符时,应用程序会崩溃,所以我假设 String() 的最大值为 32k,我正在寻找解决方法.
I have found his answer quite useful, however, when my String input exceeds 32k characters the app crashes, so I am assuming the String() is a max of 32k and am looking for a work around.
在我的应用中,如果有人搜索pancake"这个词,搜索词将被存储,当用户查看详细信息页面(比如食谱)时,pancake 这个词将突出显示.一切都适用于这个答案,但是当配方超过 32k 个字符时,应用程序会因超出索引范围的消息而崩溃.(具体错误信息:Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d43ffb4))
In my app, if someone searches for the word "pancake", the search word will be stored and when the user looks at the detail page (of lets say a recipe), the word pancake will highlight. All works well with this answer, but when the recipe exceeds 32k characters, the app crashes with exceeding index range messages. (specific error message: Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d43ffb4))
这是该问题的答案中修改后的代码:
Here is the modified code from the answer on that question:
这将打印数据:
hilightedText(str: self.recipes.last!.recipeData!)
.multilineTextAlignment(.leading)
.font(.system(size: CGFloat( settings.fontSize )))
上面这段代码显然有更多内容,但本质上,它迭代了一个数据库,找到了最后一个包含'search word'的记录,并在此处显示recipeData,它是数据库中包含的一个大字符串.
There is obviously more to this code above, but in essence, it iterates a database, and finds the last record containing 'search word' and displays the recipeData here, which is a large string contained in the database.
实现高亮文本功能:
func hilightedText(str: String) -> Text {
let textToSearch = searched
var result: Text!
for word in str.split(separator: " ") {
var text = Text(word)
if word.uppercased().contains(textToSearch.uppercased()) {
text = text.bold().foregroundColor(.yellow)
}
//THIS NEXT LINE has been identified as the problem:
result = (result == nil ? text : result + Text(" ") + text)
}
return result
}
我已经稍微修改了 Asperi 的答案以满足我的需要,并且一切都很好,除非我遇到了一个大小超过 32k 的 recipeData 条目,如前所述.
I've modified the answer from Asperi slightly to suit my needs and all works really well, unless I come across a recipeData entry that is larger than 32k in size, as stated before.
我尝试用其他一些数据类型替换 String
,但没有任何效果..
I have tried Replacing String
with a few other data types and nothing works..
有什么想法吗?
谢谢!
更新:
在评论中经过长时间的讨论后,问题的根本原因似乎是在某些时候,对于某些记录,我超过了最大的 Text("") 连接数.
After lengthy discussion in the comments, it appears that the root cause of the issue is at some point, for some records, I am exceeding the maximum Text("") concatenations.
在上面的代码中,每个单词都被拆分、评估并添加到长字符串result"中.最终看起来像这样:Text("word") + Text(" ") + Text("Word")
等等.
In the above code, each word is split out, evaluated and added to the long string "result" which winds up looking like this:
Text("word") + Text(" ") + Text("Word")
and so on.
这样做了,所以我可以轻松地为每个单词应用颜色属性,但似乎一旦我达到一定数量的单词(小于 32k,一个记录是 22k 并崩溃),应用程序就会崩溃.
This is done, so I can easily apply color attributes per word, but it would seem that once I hit a certain number of words (which is less that 32k, one record was 22k and crashed), the app crashes.
Leo 建议将 https://stackoverflow.com/a/59531265/2303865 这个帖子作为替代方案,我会必须尝试实现它.
Leo suggested https://stackoverflow.com/a/59531265/2303865 this thread as an alternative and I will have to attempt to implement that instead.
谢谢..
推荐答案
嗯...意外的限制...无论如何 - 学习新的东西.
Hmm... unexpected limitation... anyway - learn something new.
好的,这里是改进的算法,应该可以消除这个限制.
Ok, here is improved algorithm, which should move that limitation far away.
使用 Xcode 12/iOS 14 测试.(还更新了参考主题 在 SwiftUI 中突出显示文本的特定部分)
Tested with Xcode 12 / iOS 14. (also updated code in referenced topic Highlight a specific part of the text in SwiftUI)
func hilightedText(str: String, searched: String) -> Text {
guard !str.isEmpty && !searched.isEmpty else { return Text(str) }
var result = Text("")
var range = str.startIndex..<str.endIndex
repeat {
guard let found = str.range(of: searched, options: .caseInsensitive, range: range, locale: nil) else {
result = result + Text(str[range])
break
}
let prefix = str[range.lowerBound..<found.lowerBound]
result = result + Text(prefix) + Text(str[found]).bold().foregroundColor(.yellow)
range = found.upperBound..<str.endIndex
} while (true)
return result
}
这篇关于超过最大文本(“")连接长度 - SwiftUI -的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!