如何扩展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;
*/
所以我尝试使用委托来处理具有相同功能的所有需要的事件:
@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(): 索引 (18446744073709551615) 超出数组 界限 (0) * 由于未捕获的异常“NSRangeException”而终止应用程序,原因: '*** NSRunStorage, _NSBlockNumberForIndex(): 数组之外的索引 (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 版本中一切正常。
我需要做什么来扩展这门课?
According to documentation, I try to subclass NSTextStorage and use it in text view:
/*
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;
*/
So I try to use delegate, to handle all needed events with same functionality:
@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
It is no matter what I'm use as delegate: NSTextStorage or NSMutableAttributedString, The result is the same:
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)'
Stack trace:
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:]
Termination start when I try to call
[textView insertText:@"123"];
But in standard NSTextStorage version all works properly.
What I need to do to extend this class ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
除了需要实现的 NSAttributedString 原始方法之外,我相信您还需要在
replaceCharactersInRange:withString:
的重写中调用edited:range:changeInLength:
和setAttributes:range:
分别。像这样的东西:
In addition to the NSAttributedString primitive methods that need implemented, I believe you also need to make a call to
edited:range:changeInLength:
inside your overrides ofreplaceCharactersInRange:withString:
andsetAttributes:range:
respectively.Something like:
NSTextStorage 文档在这方面有点含糊。您在问题中引用的关于仅需要覆盖 2 个 NSMutableAttributedString 基元的评论仅意味着您不必覆盖其他 NSMutableAttributedString 基元。
您仍然需要重写 NSAttributedString 超类的原语。这意味着您需要实现
-attributesAtIndex: effectiveRange:
、-length
和-string
。我注意到您确实包含了-string
的实现,因此剩下的两个应该可以做到这一点。如果您添加:
...那么希望它能解决这个问题。
The
NSTextStorage
documentation is a little bit vague in this area. The comment you quote in your question, about only needing to override 2 of theNSMutableAttributedString
primitives only means that you don't have to override the otherNSMutableAttributedString
primitives.You still have to override the primitives for the
NSAttributedString
superclass. Which means you need to implement-attributesAtIndex:effectiveRange:
,-length
and-string
. I notice you did include an implementation of-string
, so the two remaining ought to do it.If you add:
... then hopefully it will fix this problem.