NSRange用长字符串崩溃

时间:2018-10-13 11:46:08

标签: ios swift nsattributedstring nsrange

我有一个要分割的属性字符串,以便可以在表视图中使用它。表格视图中的每个项目都有一个标题和一些内容。当字符串文件小于100kb时,代码可以正常工作;但是,如果字符串文件大于100kb,则代码会崩溃。

属性字符串如下:

###Title###
Foobar some title{
    NSColor = "kCGColorSpaceModelMonochrome 0.37475 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}
{
    NSColor = "kCGColorSpaceModelRGB 1 0 0 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}###Content###
{
    NSColor = "kCGColorSpaceModelMonochrome 0.37475 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}BarFoo some content{
    NSColor = "kCGColorSpaceModelMonochrome 0.37475 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}
{
    NSColor = "kCGColorSpaceModelRGB 0.99216 0.60392 0 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}###End###{
    NSColor = "kCGColorSpaceModelMonochrome 0.37475 1 ";
    NSFont = "<UICTFont: 0x7b7f2ea0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";
    NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    \"28.3L\",\n    \"56.65L\",\n    85L,\n    \"113.35L\",\n    \"141.7L\",\n    \"170.05L\",\n    \"198.4L\",\n    \"226.75L\",\n    \"255.1L\",\n    \"283.45L\",\n    \"311.8L\",\n    \"340.15L\"\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
}

原始字符串表示形式如下:

###Title###
Foobar some title
###Content###
BarFoo some content
###End###

我的代码:

struct WatchItem {
    let attributedTitle: NSAttributedString
    let attributedContent: NSAttributedString
}

class func splitAttributedString(attributedString: NSAttributedString) -> [WatchItem] {

    var attributedString = attributedString
    var string = attributedString.string
    var items = [WatchItem]()

    while true {
        guard let titleRange = string.range(of: "###Title###") else { break }
        guard let contentRange = string.range(of: "###Content###") else { break }
        guard let endRange = string.range(of: "###End###") else { break }

        guard contentRange.lowerBound > titleRange.upperBound,
            endRange.lowerBound > contentRange.upperBound else {
            items.append(getErrorItem())
            break
        }

        let titleNSRange = NSRange(titleRange.upperBound..<contentRange.lowerBound, in: string)
        let title = attributedString.attributedSubstring(from: titleNSRange)

        let contentNSRange = NSRange(contentRange.upperBound..<endRange.lowerBound, in: string)
        let content = attributedString.attributedSubstring(from: contentNSRange)

        let item = WatchItem(attributedTitle: title, attributedContent: content)
        items.append(item)

        print("-----------")
        print(title)
        print(content)
        print("-----------")

        let restNSRange = NSRange(endRange.upperBound..<string.endIndex, in: string)

        //Shorten the strings to iterate over them again
        attributedString = attributedString.attributedSubstring(from: restNSRange)

        //This line crashes
        string = String(string[endRange.upperBound..<string.endIndex])
    }
    return items
}

class func getErrorItem() -> WatchItem {
    return WatchItem(attributedTitle: NSAttributedString(string: "Something went wrong with your formatting"), attributedContent: NSAttributedString(string: "Please check the syntax.\n\n ###Title###\nYour Title\n###Content###\nYour Content\n###End###"))
}

因此,当使用大量这些归因字符串时,代码可以正常工作。但是当字符串太长时,我会得到一个EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)异常。

谁能告诉我我错过了什么或者我的代码有什么问题?

0 个答案:

没有答案