text storage aggregator
text storage aggregator
- Subject: text storage aggregator
- From: Todd Ransom <email@hidden>
- Date: Thu, 23 Feb 2006 09:37:48 -0700
I have a text storage subclass that uses an array of NSTextStorage
objects as its backing store. The goal is to take a series of text
storage objects and present them to the user as a single blob of text.
This works fine as long as the aggregator is read-only. I call this
method during init to build up the contents and again whenever one of
the component text storage objects changes:
// uses text storage primitives indirectly
- (void)buildContentsString {
[self deleteCharactersInRange: NSMakeRange(0, [self length])];
NSEnumerator *e = [components objectEnumerator];
NSTextStorage *thisTextStorage;
while (thisTextStorage = [e nextObject]) {
[self appendAttributedString: thisTextStorage];
[self appendAttributedString: [[[NSAttributedString alloc]
initWithString: @"\n"] autorelease]];
}
}
This indirectly uses the text storage primitives, which are simply
the canonical methods posted at http://www.cocoadev.com/index.pl?
NSTextStorage
Now I would like to make the aggregator read-write. My strategy is to
have the text storage primitives find the appropriate component text
storage object, modify it, and rely on notifications for the
aggregator to update its displayed text. To do this, I need a method
of building the display string that does not rely on the text storage
primitives like the method above. So I re-wrote the above method as
follows:
// modifies attributedstring directly
- (void)buildContentsString {
NSAttributedString *newlineAttrString = [[NSAttributedString alloc]
initWithString: @"\n"];
int origLen = [contents length];
[contents deleteCharactersInRange: NSMakeRange(0, [contents length])];
[self edited: NSTextStorageEditedAttributes|
NSTextStorageEditedCharacters
range: NSMakeRange(0, origLen) changeInLength: 0 - origLen];
NSEnumerator *e = [components objectEnumerator];
NSTextStorage *thisTextStorage;
while (thisTextStorage = [e nextObject]) {
int thisTextStorageLen = [thisTextStorage length];
[contents appendAttributedString: thisTextStorage];
int contentsLen = [contents length];
[self edited: NSTextStorageEditedAttributes|
NSTextStorageEditedCharacters
range: NSMakeRange(contentsLen - thisTextStorageLen, 0)
changeInLength: thisTextStorageLen];
[contents appendAttributedString: newlineAttrString];
[self edited: NSTextStorageEditedAttributes|
NSTextStorageEditedCharacters
range: NSMakeRange(contentsLen, 0) changeInLength: 1];
}
[newlineAttrString release];
}
My goal at this point is to have the aggregator exhibit the same read-
only behavior and update when one of its component text storage
objects changes. I thought the two methods above were doing the same
thing. But when I use the second method I get a crash on the second
edit to one of the component text storage objects. So my question is:
why does the second method not work just like the first? How can I
make changes to the contents of my text storage class without going
through the primitives (which will operate directly on the underlying
backing store)?
thanks,
Todd Ransom
Return Self Software
http://returnself.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden