• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Applying temporaryAttributes from processEditing (_fillGlyphHoleForCharacterRange: crash)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Applying temporaryAttributes from processEditing (_fillGlyphHoleForCharacterRange: crash)


  • Subject: Applying temporaryAttributes from processEditing (_fillGlyphHoleForCharacterRange: crash)
  • From: Keith Blount <email@hidden>
  • Date: Tue, 6 Oct 2009 09:20:03 -0700 (PDT)

Hello,

I’m attempting to add temporary attributes (all of which do not require layout) to text as soon as it has been edited if it has a custom attribute applied (much how the text system automatically applies linkTextAttributes to any text with an NSLinkAttributeName attribute - although from my various tests and NSLogging it seems that the text system does that under the hood using some internal magic and doesn’t use temporary attributes). In another thread on a related issue Aki Inoue was kind enough to point out that I could override NSLayoutManager’s -showPackedGlyphs:etc... to change the colour of the text, but that doesn’t handle underlines or strikethroughs, for which I still need to apply temporary attributes.

My current solution is to try to override my custom text storage’s -processEditing method to iterate through the layout managers and apply any necessary temporary attributes there, something like this:

- (void)processEditing
{
	[super processEditing];

	NSRange dirtyRange = [self editedRange];
	if (dirtyRange.length == 0)
		return;

	NSEnumerator *e = [[self layoutManagers] objectEnumerator];
	NSLayoutManager *lm;
	while (lm = [e nextObject])
	{
		if (dirtyRangeHasMyCustomAttribute)
		[lm addTemporaryAttributes:tempAttribs forCharacterRange:dirtyRange];
	}
}

However, the above has massive problems. In certain circumstances it causes this crash:

-[KBLayoutManager _fillGlyphHoleForCharacterRange:startGlyphIndex:desiredNumberOfCharacters:] *** attempted glyph generation while textStorage is editing.  It is not valid to cause the layoutManager to do glyph generation while the textStorage is editing (ie the textStorage has been sent a beginEditing message without a matching endEditing.)

I’m not entirely sure why, as I’ve NSLogged all of the beginEditing and endEditing messages and this code is only ever call after the last -endEditing, so beginEditing and endEditing should are matching (I even tested it out by putting it into -endEditing and processing things only after calling [super endEditing] but had the same crash).

I can avoid the crash by putting the temporary attribute application code into a separate method and calling it after a zero delay like this:

- (void)processEditing
{
	[super processEditing];

	[self performSelector:@selector(applyTempAttributesIfNecessaryToRange:) withObject:[NSValue valueWithRange:[self editedRange] afterDelay:0];
}

But this seems fragile to me. I’m not entirely sure why calling the same code after a delay of 0 would prevent the crash, or confident that it will work in all situations.

Has anyone tried to do something similar and found a better solution to what I’m trying to do?

Many thanks in advance and all the best,
Keith



_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Re: NSOutlineView - Automatically select newly added item - Help needed
  • Next by Date: Re: NSLayoutManager and best override point for temporary attributes
  • Previous by thread: Re: grouping undo across method calls in CoreData [with possible solutions]
  • Next by thread: Triggering a Method when a Core Data Property is Altered.
  • Index(es):
    • Date
    • Thread