2013-11-20 23 views
0

我的應用程序使用我自己的NSTextStorage的子類,並且一切正常,直到Mavericks。即使使用最精簡的版本,只要我用它初始化文本視圖,我就會得到一個異常。我閱讀了文檔,也看了一下How to extend NSTextStorage?。希望你們中的一位知道蘋果是否改變了一些事情,或者如果我做錯了什麼。在小牛上繼承NSTextStorage時與範圍相關的異常

信息,你可能需要幫我:

例外:

TextViewCheck [12542:303]:異常*** NSRunStorage(0x6000000a4200),_replaceElements():替換範圍{0,929}將 延伸超出當前運行存儲大小928.在排版佈局管理器期間引發 NSLayoutManager:0x100106a80
1容器,文本備份g有928個字符 所選字符範圍{0,0}親和力:上游粒度:字符 標記字符範圍{0,0} 當前擁有928個字形。
字形樹內容:928個字符,928個字形,1個節點,64個節點字節,960個 存儲字節,1024個總字節,每個字符1.10個字節,每個字形1.10個字節 佈局樹內容:928個字符,928個字形,字符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作爲子視圖命名容器和一個隨機字符串字符串1

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]; 
+1

它看起來像你的一個範圍內的錯誤的錯誤。 –

+0

@BradAllred:對,但我不知道我在哪裏創建該錯誤或我如何解決它。顯然我使用的字符串有928個字符,直到那個崩潰只有方法 - (id)init ..., - (NSString *)字符串和 - (NSDictionary *)attributesAtIndex ...被調用。並在屬性的索引範圍是(928,0) –

+1

註釋掉所有覆蓋除第一個和運行它。如果它沒有崩潰,請添加下一個方法並重復,直到找到罪魁禍首。我的錢是'replaceCharactersInRange' –

回答

0

在replaceCharactersInRange,要設置origLen到[自身長度],並且一行之後,您將通過[自身長度]減去origLen來計算changeInLength,這是有效的:

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

我覺得你寧願:

changeInLength: self.length - str.length]; 
+0

嘿,我試了一下,但它沒有幫助。與此同時,我寫了Apple支持,他們認爲這是該框架某處的錯誤。我將在他們的錯誤跟蹤器中報告一個錯誤。我的解決方法是不要替換'TextStorage',而是替換它的'String'。 –