[英]How to extend NSTextStorage?
根據文檔,我嘗試子類化NSTextStorage並在文本視圖中使用它:
/*
NSTextStorage is a semi-abstract subclass of NSMutableAttributedString. It
implements change management (beginEditing/endEditing), verification of
attributes, delegate handling, and layout management notification. The one
aspect it does not implement is the actual attributed string storage --- this is
left up to the subclassers, which need to override the two
NSMutableAttributedString primitives:
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range;
*/
所以我嘗試使用delegate來處理具有相同功能的所有需要的事件:
@implementation MyTextStorage
- (id) init {
self = [super init];
if (self != nil) {
storage = [[NSMutableAttributedString alloc] init];
}
return self;
}
- (void) dealloc {
[storage release];
[super dealloc];
}
- (NSString *) string {
return [storage string];
}
- (void) replaceCharactersInRange:(NSRange)range withString:(NSString *)str {
[storage replaceCharactersInRange:range withString:str];
}
- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range {
[storage setAttributes:attrs range:range];
}
@end
無論我使用什么作為委托:NSTextStorage或NSMutableAttributedString,結果都是一樣的:
引發了未捕獲的異常* NSRunStorage,_ NSBlockNumberForIndex():index(18446744073709551615)超出數組邊界(0)*由於未捕獲的異常'NSRangeException'終止應用程序,原因:'*** NSRunStorage,_ NSBlockNumberForIndex():index(18446744073709551615)超出數組邊界(0)'
堆棧跟蹤:
0 CoreFoundation 0x00007fff840cd7b4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff885390f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff840cd5d7 +[NSException raise:format:arguments:] + 103
3 CoreFoundation 0x00007fff840cd564 +[NSException raise:format:] + 148
4 AppKit 0x00007fff86cc6288 _NSBlockNumberForIndex + 86
5 AppKit 0x00007fff86cc71d5 -[NSLayoutManager textContainerForGlyphAtIndex:effectiveRange:] + 364
6 AppKit 0x00007fff86d1f121 -[NSTextView(NSSharing) didChangeText] + 340
7 AppKit 0x00007fff86d44b68 -[NSTextView insertText:replacementRange:] + 2763
8 CocoaCalculator 0x0000000100002312 -[CalcTextView insertText:] + 65
9 CocoaCalculator 0x00000001000027ac -[CalcTextContainer initWithFrame:] + 1176
10 AppKit 0x00007fff86c23d44 -[NSCustomView nibInstantiate] + 646
11 AppKit 0x00007fff86b7be17 -[NSIBObjectData instantiateObject:] + 259
12 AppKit 0x00007fff86b7b202 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 336
13 AppKit 0x00007fff86b7988d loadNib + 226
14 AppKit 0x00007fff86b78d9a +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:]
我嘗試打電話時終止開始
[textView insertText:@"123"];
但是在標准的NSTextStorage版本中,一切正常。
我需要做些什么來擴展這個類?
除了需要實現的NSAttributedString原始方法之外,我相信你還需要調用edited:range:changeInLength:
在replaceCharactersInRange:withString:
和setAttributes:range:
覆蓋setAttributes:range:
。
就像是:
- (void) replaceCharactersInRange:(NSRange)range withString:(NSString *)str {
[storage replaceCharactersInRange:range withString:str];
[self edited:NSTextStorageEditedCharacters range:range changeInLength:[str length] - range.length];
}
- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range {
[storage setAttributes:attrs range:range];
[self edited:NSTextStorageEditedAttributes range:range changeInLength:0];
}
NSTextStorage
文檔在這方面有點模糊。 您在問題中引用的注釋,只需要覆蓋2個NSMutableAttributedString
原語只意味着您不必重寫其他NSMutableAttributedString
原語。
您仍然必須覆蓋NSAttributedString
超類的基元。 這意味着您需要實現-attributesAtIndex:effectiveRange:
-length
和-string
。 我注意到你確實包含了-string
的實現,所以剩下的兩個應該這樣做。
如果你添加:
- (NSUInteger)length
{
return [storage length];
}
- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range
{
return [storage attributesAtIndex:location effectiveRange:range];
}
...然后希望它能解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.