编辑属性字符串时调用哪种替换方法?

Which replacement method is called when editing an attributed string?

NSMutableAttributedString定义了两种字符串替换方式:

func replaceCharacters(in range: NSRange, 
                       with str: String)

func replaceCharacters(in range: NSRange, 
                with attrString: NSAttributedString)

我创建了 NSTextStorage 的子类,它又是 NSMutableAttributedString 的子类。在该子类中,我覆盖了上述两种方法。

令我惊讶的是,当我在我的文本视图中键入或粘贴某些内容时,从不调用后一种方法(传递属性替换字符串)。每次调用的只是纯字符串替换方法。

这引出了我的问题:
当用户在文本视图中编辑文本时,这两个方法实际上是根据什么规则调用的

(我需要在我的文本存储中执行不同的操作,这取决于属性替换字符串是否包含特定类型的文本附件。但是如果从未调用属性字符串的替换方法,我看不出如何做出这种区分。)

函数

func replaceCharacters(in range: NSRange, 
                with attrString: NSAttributedString)

实际上从未调用过。

从文档(下方)可以清楚地看出,应该使用 replaceCharactersInRange:withString: 的组合,然后调用 setAttributes:range:

/* Note for subclassing 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 in addition to two NSAttributedString primitives:

  • (NSString *)string;
  • (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range;

  • (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;

  • (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range; These primitives should perform the change then call edited:range:changeInLength: to get everything else to happen. */

确保您自定义了这些方法的实现。

这也是 AppKit 实现的方式 NSTextView: