【发布时间】:2017-06-02 00:33:41
【问题描述】:
我的应用有一个供稿,其中的帖子可以包含 URL、#hashtags 和 @mentions。我使用名为 ActiveLabel 的 pod 显示它们。这个 pod 做得很好,但是滚动时我的提要稍微滞后。我的提要是UICollectionView,细胞生成稍有滞后。我在滚动时分析了我的应用程序,并分析了滞后峰值。延迟几乎不明显,但让我很恼火。
如您所见,主要的违规者是 NSRegularExpression 搜索。
我尝试通过在没有数据类型实例时禁用数据检测来稍微优化这一点,使用.contains()。这使它稍微快了一点,但滞后峰值仍然存在。
let enabledTypes:[ActiveType] = {
var types = [ActiveType]()
if ad.caption.current.string.contains("#") { types.append(.hashtag) }
if ad.caption.current.string.contains("@") { types.append(.mention) }
if ad.caption.current.string.contains("://") { types.append(.url) }
if ad.caption.canExpand { types.append(seeMore) }
return types
}()
label.enabledTypes = enabledTypes
我还跟踪了this article 中的每一步,这有点帮助,但还不够。所以我需要修复正则表达式。
ActiveLabel 使用的正则表达式是
static let hashtagPattern = "(?:^|\\s|$)#[\\p{L}0-9_]*"
static let mentionPattern = "(?:^|\\s|$|[.])@[\\p{L}0-9_]*"
static let urlPattern = "(^|[\\s.:;?\\-\\]<\\(])" + "((https?://|www\\.|pic\\.)[-\\w;/?:@&=+$\\|\\_.!~*\\|'()\\[\\]%#,☺]+[\\w/#](\\(\\))?)" + "(?=$|[\\s',\\|\\(\\).:;?\\-\\[\\]>\\)])"
它与它们一起使用
static func getElements(from text: String, with pattern: String, range: NSRange) -> [NSTextCheckingResult]{
guard let elementRegex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive]) else { return [] }
return elementRegex.matches(in: text, options: [], range: range)
}
搜索其他正则表达式以检测主题标签和提及,但我没有找到任何有所作为的东西。
我试图在后台线程上布局标签,但这显然崩溃了,因为 UI 不喜欢在后台线程上完成。我可以重写 ActiveLabel 以主要在我可以使用回调而不是返回类型的后台线程上工作,但我想避免这种情况。
我检测到数据的一些字符串示例:
“Arnie 说,Aspen。Str. Small。Varm og God jakke。Veldig fin på!Fremstår ubrukt。Kun brukt et par ganger,rett og slett fordi jeg har alt for mange jakker????#urban #arnie #说#aspen #ubrukt”
“Skjorte pent brukt iorganisk bomull fra tom 裁缝 originalpris 300kr #organisk #bomullsjorte #bomull #flower #floral”
“Jean Paul genser i 100% ull, pent brukt✨ er i str.m, men veldig liten, passer xs-s! \n #jeanpaul #genser #classy #litebrukt #brun #ull”
如您所见,我们的用户主要是标签的东西,所以一个是最重要的。
有什么方法可以改进NSRegularExpression 或正则表达式以避免性能下降?
【问题讨论】:
-
您的
urlPattern模式不是最佳的。匹配与模式不匹配的长字符串时可能会导致速度变慢。此外,"(?:^|\\s|$)#[\\p{L}0-9_]*"将匹配类似#的字符串。我认为您可以使用static let hashtagPattern = "\\B#[\\p{L}0-9_]+"和static let mentionPattern = "\\B@[\\p{L}0-9_]+"。 -
改用
NSDataDetector会有帮助吗? -
@WiktorStribiżew ActiveLabel 框架在另一个位置过滤长度,但我会用你的表达式来测试。
标签: ios objective-c regex swift nsregularexpression