Re: text storage aggregator
Re: text storage aggregator
- Subject: Re: text storage aggregator
- From: Martin Wierschin <email@hidden>
- Date: Thu, 23 Feb 2006 14:54:38 -0800
Hello Todd,
But when I use the second method I get a crash on the second edit
to one of the component text storage objects.
I suspect this is because your aggregator storage is basically
empty. The first call to edited will always pass a range of (0,0)
which is never unsafe. This issue with your second call is that your
parent class (NSTextStorage) may attempt to access characters/
attributes at the index "contentsLen" (or at least verify that they
can be accessed). If your aggregator subclass has not overridden the
primitive methods (eg: length, attributesAtIndex:effectiveRange:,
etc) the "contentsLen" index will be out of bounds because your
subclass is effectively empty (eg: you have never inserted text into
it, just your "contents" ivar).
In any case, unless you really need to copy all that data back and
forth between your constituent storages (eg: to do some special
transformations), I would suggest a different approach for your
aggregator. Simply override all the text storage primitives to call
through to your constituent storages, (warning: typed in Mail) eg:
- (NSDictionary*) attributesAtIndex:(unsigned)charIdx effectiveRange:
(NSRange*)effRngPtr
{
// ask the proper constituent storage for its attributes
NSTextStorage* subTs;
NSRange subRng = [self _convertGlobalRange:NSMakeRange(charIdx,0)
toSubTextStorage:&subTs];
NSRange subEffRng;
NSDictionary* attrs = [subTs attributesAtIndex:subRng.location
effectiveRange:&subEffRng];
// convert back to global coordinates if they need to know the
effective range
if( NULL != effRngPtr ) {
NSRange effRng = [self _convertSubRange:subEffRng
fromSubTextStorage:subTs];
*effRngPtr = effRng;
}
return attrs;
}
- (void) setAttributes:(NSDictionary*)attrs range:(NSRange)rng
{
unsigned at = rng.location, lim = NSMaxRange(rng);
while( at < lim ) {
NSTextStorage* subTs;
NSRange subRng = [self _convertGlobalRange:NSMakeRange(at, lim -
at) toSubTextStorage:&subTs];
[subTs setAttributes:attrs range:subRng];
at += subRng.length;
}
}
You'll need to define those mapping methods (eg:
_convertGlobalRange) and worry about editing notifications and all
that, but I think this approach will pay for its complexity with a
cleaner and more scalable design. One additional caveat: the -string
and -mutableString methods need to return a custom subclass that
knows how to talk to your aggregator.
Hopefully this gets you started. I think you'll find that the Cocoa
text system is largely a pleasure to work with once you get your
bearings. Cheers,
~Martin
_______________________________________________
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