0

我的应用程序使用我自己的子类,NSTextStorage并且在 Mavericks 之前一切正常。即使使用最精简的版本,只要我用它初始化一个文本视图,我就会得到一个异常。我阅读了文档并查看了如何扩展 NSTextStorage?. 希望你们中的一个人知道苹果是否改变了某些东西,或者我做错了什么。

您可能需要帮助我的信息:

例外:

TextViewCheck[12542:303]:异常 *** NSRunStorage (0x6000000a4200),_replaceElements():替换范围 {0, 929} 超出当前运行存储大小 928。在排版布局管理器 NSLayoutManager 期间引发 NSLayoutManager:0x100106a80
1 个容器,文本支持有 928字符选择字符范围 {0, 0} 亲和力:上游粒度:字符标记字符范围 {0, 0} 目前持有 928 个字形。
字形树内容:928 个字符,928 个字形,1 个节点,64 个节点字节,960 个存储字节,1024 个总字节,每个字符 1.10 个字节,每个字形 1.10 个字节 布局树内容:928 个字符,928 个字形,0 个铺层字形,0 个铺层行片段,1 个节点,64 个节点字节,0 个存储字节,64 个总字节,每个字符 0.07 个字节,每个字形 0.07 个字节,每个铺设线片段 0.00 个铺设字形,每个铺设线片段 0.00 个字节,字形范围 {0 928}。无视...

回溯

thread #1: tid = 0x137013, 0x00007fff8ad7e44e AppKit`_NSGlyphTreeGetGlyphsInRange + 1179, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x1002c0000)

frame #0: 0x00007fff8ad7e44e AppKit`_NSGlyphTreeGetGlyphsInRange + 1179
frame #1: 0x00007fff8ad7dfa1 AppKit`-[NSLayoutManager getGlyphsInRange:glyphs:characterIndexes:glyphInscriptions:elasticBits:bidiLevels:] + 92
frame #2: 0x00007fff8ad4d8b6 AppKit`-[NSATSGlyphStorage setGlyphRange:characterRange:] + 3724
frame #3: 0x00007fff8ad4c8be AppKit`-[NSATSTypesetter _ctTypesetter] + 306
frame #4: 0x00007fff8ad4baf9 AppKit`-[NSATSLineFragment layoutForStartingGlyphAtIndex:characterIndex:minPosition:maxPosition:lineFragmentRect:] + 85
frame #5: 0x00007fff8ad4a64e AppKit`-[NSATSTypesetter _layoutLineFragmentStartingWithGlyphAtIndex:characterIndex:atPoint:renderingContext:] + 2777
frame #6: 0x00007fff8ad7dc79 AppKit`-[NSATSTypesetter layoutParagraphAtPoint:] + 149
frame #7: 0x00007fff8b3f5b45 AppKit`-[NSTypesetter _layoutGlyphsInLayoutManager:startingAtGlyphIndex:maxNumberOfLineFragments:maxCharacterIndex:nextGlyphIndex:nextCharacterIndex:] + 4043
frame #8: 0x00007fff8ad7cc9d AppKit`-[NSTypesetter layoutCharactersInRange:forLayoutManager:maximumNumberOfLineFragments:] + 202
frame #9: 0x00007fff8ad7cb81 AppKit`-[NSATSTypesetter layoutCharactersInRange:forLayoutManager:maximumNumberOfLineFragments:] + 1107
frame #10: 0x00007fff8ad7b219 AppKit`-[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 1306
frame #11: 0x00007fff8ae24ad9 AppKit`_NSFastFillAllLayoutHolesForGlyphRange + 1435
frame #12: 0x00007fff8ae6ddbd AppKit`-[NSLayoutManager(NSPrivate) _firstPassGlyphRangeForBoundingRect:inTextContainer:okToFillHoles:] + 309
frame #13: 0x00007fff8ae6cea4 AppKit`-[NSLayoutManager(NSPrivate) _glyphRangeForBoundingRect:inTextContainer:fast:okToFillHoles:] + 875
frame #14: 0x00007fff8add81b2 AppKit`-[NSTextView setNeedsDisplayInRect:avoidAdditionalLayout:] + 1466
frame #15: 0x00007fff8acb4222 AppKit`-[NSView setNeedsDisplay:] + 81
frame #16: 0x00007fff8add68d9 AppKit`-[NSTextView setTextContainer:] + 699
frame #17: 0x00007fff8add651a AppKit`-[NSTextContainer setTextView:] + 263
...

编码:

TTTSimpleTextStorage.m

@implementation TTTSimpleTextStorage

- (id)initWithAttributedString:(NSAttributedString *)attrStr {
    if (self = [super init]) {
        contents = attrStr ? [attrStr mutableCopy] :
        [[NSMutableAttributedString alloc] init];
    }
    return self;
}


- init {
    return [self initWithAttributedString:nil];
}

- (NSString *)string {
    return [contents string];
}

- (NSDictionary *)attributesAtIndex:(NSUInteger)location
                 effectiveRange:(NSRange *)range {
    return [contents attributesAtIndex:location effectiveRange:range];
}

- (void)replaceCharactersInRange:(NSRange)range withString:(NSString
                                                        *)str {
    NSInteger origLen = [self length];
    [contents replaceCharactersInRange:range withString:str];
    [self edited:NSTextStorageEditedCharacters range:range
          changeInLength:[self length] - origLen];
}

- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range {
    [contents setAttributes:attrs range:range];
    [self edited:NSTextStorageEditedCharacters range:range
       changeInLength:0];
}

@end

我如何使用它

这是在 MainWindowController - awakeFromNib 中,窗口 IBOutlet 有一个 NSView 作为名为container的子视图和一个随机字符串string1

nts1 = [[TTTSimpleTextStorage alloc] initWithString:string1];

NSLayoutManager* lm1 = [[NSLayoutManager alloc] init];
[nts1 addLayoutManager:lm1];

NSTextContainer* tc1 = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(400, 280)];
[lm1 addTextContainer:tc1];


tv1 = [[NSTextView alloc] initWithFrame:NSMakeRect(40, 20, 400, 280) textContainer:tc1];  // here it crashes

[self.container addSubview:tv1];
[self.window makeKeyAndOrderFront:nil];
[self.window makeFirstResponder:tv1];
4

1 回答 1

0

在 replaceCharactersInRange 中,您将 origLen 设置为 [self length],然后在一行之后,您通过 [self length] 减去 origLen 来计算 changeInLength,这实际上是:

NSInteger origLen = self.length;
// ...
changeInLength: origLen - self.length

我想你宁愿想要:

changeInLength: self.length - str.length];
于 2013-12-12T13:05:14.523 回答