• 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
Re: text storage aggregator
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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
  • Follow-Ups:
    • Re: text storage aggregator
      • From: Todd Ransom <email@hidden>
References: 
 >text storage aggregator (From: Todd Ransom <email@hidden>)

  • Prev by Date: Re: Addendum: Fetch Requests and NSDecimalNumbers --> Fetch on Transient Values
  • Next by Date: Re: NSXMLParserErrorDomain 4
  • Previous by thread: text storage aggregator
  • Next by thread: Re: text storage aggregator
  • Index(es):
    • Date
    • Thread