根据文档,我尝试子类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,结果是一样的:
An uncaught exception was raised
* NSRunStorage,_NSBlockNumberForIndex(): index (18446744073709551615) beyond array
bounds (0)
* Terminating app due to uncaught exception ‘NSRangeException’,reason:
‘*** NSRunStorage,
_NSBlockNumberForIndex(): index (18446744073709551615) beyond array
bounds (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原始方法之外,我相信还需要调用编辑:range:changeInLength:在replaceCharactersInRange:withString:和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]; }