Friday, April 22, 2011

Spotlighter and NSMetadataQuery

Apple's Spotlighter example tries to help us to become more familiar with NSMetadataQuery.
But it also contains a nasty bug, that let your derived code crash or let it become slower and slower.
The Spotlighter example does not crash, of course...

In -createSearchPredicate the example's author proposes to simply call
-setPredicate: followed by -startQuery.

Doing it this way produces multiple MDQuery instances under the hood.
All the created MDQuery objects do weakly reference your (single) NSMetadataQuery instance.
But your NSMetadataQuery instance only references one of them.
This does not pop up as long as you do not release the NSMetadataQuery instance in your code.

But if the instance of NSMetadataQuery gets freed, all the obsolete MDQuery objects continue to listen to changes (live update). On changes they try to invoke the freed NSMetadataQuery instance, which lets your app crash. NSMetadataQuery's -stopQuery method just frees the one and only MDQuery it references internally.

Solution:

// stop query if it already has been started
if ([myQuery isStarted] == YES)
[myQuery stopQuery];

// setting the predicate
[myQuery setPredicate:myPredicate];

// start or restart the query
if ([myQuery isStarted] == NO || [myQuery isStopped] == YES)
[myQuery startQuery];

Tuesday, December 2, 2008

Aquatic Prime

If you are looking for a free registration method for your applications take a look at AquaticPrime framework.

Software update framework

If you are looking for a free software update framework take a look at sparkle by Andy Matuschak.

Per-object ordered relationships using Core Data

For all people interested in how to make ordered relationships possible in CoreData i recommend to read a post by Brian Webster (Fat Cat Software). It is a good starting point.

Saturday, June 23, 2007

CoreData and transient properties

If you are interested in transient properties with CoreData you should read this article written by Jakob Stoklund Olesen.

Tuesday, May 22, 2007

DeviceN & Separation color space

Though cocoa is able to display PDFs that contain colors of DeviceN or separation color spaces you cannot create those spaces programatically.
That means, you cannot create instances of colors using DeviceN or separation color spaces. And finally there is a lack of support for other color related stuff like 'overprint black' and others we'd need to create professional PDFs.
Remember that all this depends on underlying Quartz graphics engine.
So new color features first have to be added to Quartz before propagated to Cocoa.

BUT: Take a look at spot color picker for OSX.
It manages to add spot colors to documents of any app that supports OSX color picker.
So how is this possible?!
Hint: This color picker lists instances of NSColor of a dummy gray color space marked by a special ICC profile containing the needed additional information about the spot color. Then it hooks into the PDF/PS generation process and appends additional objects to the generated PDF using the data taken from the ICC profile. This hook only works with spot color picker installed.
So if you hand over a document with spot colors to someone who hasn't installed spot picker you won't get the correct results when printing it to PDF.
This is the most intelligent Cocoa/Quartz hack I have ever seen. Cool stuff.

Sunday, May 20, 2007

NSKeyedArchiver is wasting memory

If your program has to handle a large amount of data, remember that NSKeyedArchiver's
-archiveRootObject:toFile: first encodes your document into an instance of NSData and then stores content data to disk using -writeToFile:options:error:.
For reference see according documentation of -archiveRootObject:toFile:.
That means saving a 2GB document to disk may consume n GB of RAM (2GB document + n GB as encoded data in an instance of NSData :-)
Memory consumption of course depends on output format you set to the archiver.

NSKeyedUnarchiver behaves similar:
First the data will be read from disk into an instance of NSData and then it will be decoded from there.

I really miss a direct to disk variant of coding/encoding.
I did not digged deeply into CoreData in combination with SQLite. Maybe this is something worth to take at look at, as theoretically SQLite should never need to have the whole graph in memory. But for an existing project (or if your project should be downward compatible to Panther) it's hard to accept.