My app uses lots of attributed strings in “subdocuments” which get moved into 
and out of a text edit window.

I began to wonder if I needed to add a cache for paragraph styles and string 
attributes, because when each subdocument gets loaded, I’m repetitively 
deserializing identical attributes to apply to the strings.

Today I wrote the first draft of a test to see what happens when you blindly 
and repetitively instantiate the same attributes:

  func attributedStringsWithNoCache() {
    var array = [NSAttributedString]()
    let fm = NSFontManager.sharedFontManager()
    for index in 1...30 {
      var font = NSFont( name:"Times", size:12.0 );
      font = fm.convertFont( font!, toHaveTrait:NSFontTraitMask.BoldFontMask )
      if ( index % 3 == 0 ) {
        font = fm.convertFont( font!, 
toHaveTrait:NSFontTraitMask.ItalicFontMask )
      }
      var para = NSMutableParagraphStyle();
      para.lineSpacing = 1.4
      para.alignment = NSTextAlignment.CenterTextAlignment;
      let attributes = [
        "StyleName":"Bold",
        NSFontAttributeName:font!,
        NSParagraphStyleAttributeName:para
      ];
      var attrStr = NSAttributedString( string:"Bold Para \(index)", 
attributes:attributes );
      array.append( attrStr );
    }
    for index in 1...30 {
      var font = NSFont( name:"Times", size:10.0 );
      var para = NSMutableParagraphStyle();
      para.lineSpacing = 1.2
      para.alignment = NSTextAlignment.LeftTextAlignment;
      let attributes = [
        "StyleName":"Roman",
        NSFontAttributeName:font!,
        NSParagraphStyleAttributeName:para
      ];
      var attrStr = NSAttributedString( string:"Roman Para \(index)", 
attributes:attributes );
      array.append( attrStr );
    }
    var fontDict = [NSFont:Int]()
    var attrDict = [NSDictionary:Int]()
    var paraDict = [NSParagraphStyle:Int]()
    for attrStr in array {
      attrStr.enumerateAttributesInRange(
        NSRange( location:0, length:attrStr.length ),
        options:NSAttributedStringEnumerationOptions.allZeros,
        usingBlock:{ ( attributes, Range, stop ) -> Void in
          attrDict[ attributes ] = 1
          if let para = attributes[ NSParagraphStyleAttributeName ] as? 
NSParagraphStyle {
            paraDict[ para ] = 1
          }
          if let font = attributes[ NSFontAttributeName ] as? NSFont {
            fontDict[ font ] = 1
          }
      })
    }
    println( "NO CACHE:\nFound \(fontDict.count) fonts and \(paraDict.count) 
paragraph styles in \(attrDict.count) attribute dictionaries" )
  }

I expected the result to say it found 3 fonts and 60 paragraph styles in 60 
attribute dictionaries. (I know the system uniquifies fonts.) But when I run 
the test, I get the best result possible—3 fonts and 2 paragraph styles in 3 
attribute dictionaries—as if NSAttributedString already uniquifies everything.

Is my test bad somehow, or am I really seeing that the text system already 
optimizes memory usage by uniquifying all attribute dictionaries, so I can 
forget about doing any caching of my own?

— 

Charles
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to