0

I've written a small utility to generate character glyphs as image files in order to train a CoreML image classifier. This means thousands of images. It seems to track to NSImage.lockFocus(). This method allocates offscreen and draws offscreen then caches the result. I never need the image after I create the jpg file, but I can not seem to clear the cache. This seems to be an old problem, but a search turned up no working solution was found. Is there another way to avoid caching or to force a clear? Here is one of the problem methods.

var imageInProgress = NSImage()

func makeNSImage(input:String) {
    let size = CGSize(width: 399, height: 399)
    
    // select a random font
    let selAttribIndex = Int.random(in: 0...attrArray.count-1)
    let attribInput = NSAttributedString(string: input, attributes: attrArray[selAttribIndex])
    let boundingRect = attribInput.boundingRect(with: size, options: [])
    let startX = (size.width/2 - boundingRect.width/2)
    let startY = (size.height/2 - boundingRect.height/2)
    imageInProgress = NSImage(size: CGSize(width: 400, height: 400))
    imageInProgress.lockFocus()
    imageInProgress.backgroundColor = NSColor.white
    attribInput.draw(at: CGPoint(x: startX, y: startY))
    imageInProgress.unlockFocus()
}

This routine generates a root image and I then make N augmented versions. When I lock focus to draw the symbol, the app's memory allocation jumps 5 Meg, the unlock does not give it back. I call lockFocus many times during the creation of the augments and each time the app memory allocation climbs steadily until it crumps at more than 130 Gig!

BlueskyMed
  • 765
  • 7
  • 24

1 Answers1

0

Further digging reveals that NSImage and other swift wrapped Objective C objects do not all get released by the inherent ARC in Swift! In the case of NSImage, even recache() does not do it.

The solution is to wrap the code of my main loop with an autoreleasepool {}

See Is it necessary to use autoreleasepool in a Swift program?

BlueskyMed
  • 765
  • 7
  • 24