I've Got Those NSKeyedUnarchiver Blues!

2011-12-04 Thread Stuart Rogers
I'm having a problem decoding a keyed archive, and I would appreciate
it if some kind soul here can swing the relevant clue bat...

My workspace contains three OS X projects:
* A static library: 'Splits Image Lib'.  This contains, inter alia,
  a class called SplitsTestSet, which conforms to NSCoding.
* A document-based app: 'Splits Test Set Creator'.  This creates a
  SplitsTestSet object as its model, and saves it to a file using
  NSKeyedArchiver via the document's -dataOfType:error:.
* A document-based app: 'Splits Trainer'.  This imports the files
  written by Splits Test Set Creator (but not via the document's
  -readFromData:ofType:error:).

The Creator app writes and reads its documents correctly - I can
write the data to file, restart the app, and read the data file back
in without problem.

The Trainer app is where things fall over.  It reads the file into
an NSData object and tries to decode it with NSKeyedUnarchiver's
-unarchiveWithData: but this results in:

*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class 
(SplitsTestSet)

I really don't understand why this is happening.  I'm convinced it's
not a problem with library linking, as these apps have no problem
instantiating various objects sourced from the library.  (Almost all
my Googling about this exception seem to be down to bad linking.)
For the record, both apps have 'Splits Image Lib' listed in 'Target
Dependencies' and its '.a' file in 'Link Binary with Libraries'.

So what am I doing wrong...? I suspect it's something subtly trivial.

And now for some code.  The Splits Test Set Creator reads and writes
using the following code (with error handling removed for clarity):

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
  NSData *archive = [NSKeyedArchiver archivedDataWithRootObject:self.testSet];
  return archive;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError 
**)outError
{
  SplitsTestSet* ts = [NSKeyedUnarchiver unarchiveObjectWithData:data];
  self.testSet = ts;
  return YES;
}

The Splits Trainer reads it after prompting the user for its data file:

- (void)chooseExamples:(id)sender
{
  NSOpenPanel *openPanel = [NSOpenPanel openPanel];
  // ... openPanel's configuration snipped...

  void (^handler)(NSInteger result) = ^(NSInteger result)
  {
if (result == NSFileHandlingPanelOKButton)
{
  NSURL *theUrl = [[openPanel URLs] objectAtIndex:0];
  [openPanel orderOut:nil];
  NSData *filecontents = [NSData dataWithContentsOfURL:theUrl];
  SplitsTestSet *testSet = [NSKeyedUnarchiver 
unarchiveObjectWithData:filecontents];
  self.examples = testSet;
}
  };
  [openPanel beginSheetModalForWindow:[(NSPathControl*)sender window] 
completionHandler:handler];
}

These apps are written on and for OS X 10.6...
System: XCode 4.0.2 on Mac OS X 10.6.7 Base SDK 10.6

Stuart

___

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

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


Re: I've Got Those NSKeyedUnarchiver Blues!

2011-12-04 Thread Stuart Rogers
A little earlier I wrote...

> The Trainer app is where things fall over.  It reads the file into
> an NSData object and tries to decode it with NSKeyedUnarchiver's
> -unarchiveWithData: but this results in:
> 
> *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class 
> (SplitsTestSet)
> 
> I really don't understand why this is happening.  I'm convinced it's
> not a problem with library linking, as these apps have no problem
> instantiating various objects sourced from the library.

And with that bold claim I immediately stand out to be the complete
idiot - it was a linking problem after all...

An article I found via Google suggested that if the library included
categories, then "-ObjC" should be added to "Other Linker Flags".

I'd ruled this out earlier because I didn't have any categories in my
library.  Except that I did, as class extensions (I had some properties
redefined internally as readwrite rather than the public readonly).

So that worked.

Which raises another question: if that fixed it in my misbehaving
app, why is my well-behaved app behaving well given that it
*doesn't* have that linker flag set?  Could it have anything to do
with the fact that the contents of the library were spawned off
from that app?  Consider these to be rhetorical questions - I'm
just happy that I've got over this hurdle and can now move on.

Stuart

___

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

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


Re: I've Got Those NSKeyedUnarchiver Blues!

2011-12-05 Thread Stuart Rogers
On 4 Dec 2011, at 23:09, Jens Alfke wrote:
> 
>> *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class 
>> (SplitsTestSet)
>> 
>> I really don't understand why this is happening.  I'm convinced it's
>> not a problem with library linking, as these apps have no problem
>> instantiating various objects sourced from the library.  (Almost all
>> my Googling about this exception seem to be down to bad linking.)
> 
> My suspicion is that the class SplitsTestSet is getting dead-stripped from 
> the Trainer app. Try adding the line “[SplitsTestSet class]” somewhere in the 
> code, just to force a reference to the class-name so it won’t get stripped.

This worked once I did the same for one of the four other library
classes that SplitsTestSet used.

As my projects use all the classes the library provides, I'll stick to
the -ObjC linker flag solution; adding code to solve what seems to
be a problem with over-enthusiastic link optimisation is anathema
to me.  However, this solution would definitely be worth using if I
was using only a tiny fraction of a large library.

> Also try looking at the binary using the ‘nm’ tool to check whether the class 
> symbols exist in the app.

Yes, this made it crystal clear - thanks for pointing me at 'nm' and
helping me understand the solutions.

Stuart

___

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

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


Losing my memory - a caching problem?

2010-08-17 Thread Stuart Rogers
I'm having enormous difficulty keeping tabs on memory usage in my current
project.  I'm happy that I'm not leaking anything - Build & Analyse reports no
issues, and neither does Instruments (Object Allocations and Leaks).  And yet,
when watching bulk memory usage I see my free RAM dropping like a stone
(at the expense of my inactive RAM) and within seconds it has chewed through
8GB and starts kicking off extra page files.  The active RAM usage is fairly
modest, and nearer to what I would expect.

My app is a neural network that uses signature data based upon image files.
The above symptoms are most apparent during the testing phase, which
consists of the following, repeated for several thousand image files:
1. Read in an image from file (720x576px)
2. Create a signature from the image (~7kB)
3. Discard the image
4. Apply the signature to the network.

If I doctor my code to repeatedly use the same image file then the problem
doesn't arise, which suggests to me that my code is fine but that the system
is aggressively caching image data.  Image caching is not welcome on this
occasion - I use each image file once only.

Any suggestions on how to tame this beast would be extremely welcome.

Here's the code I use to read in my images (error handling snipped for
clarity):

- (ImageSignature *)signatureForPath:(NSString *)path
{
ImageSignature *sig = nil;
NSURL *url = [NSURL fileURLWithPath:path];
NSDictionary *opts = [NSDictionary dictionaryWithObject:(id)kCFBooleanFalse
   
forKey:(NSString*)kCGImageSourceShouldCache];
CGImageSourceRef src = 
CGImageSourceCreateWithURL((CFURLRef)url,(CFDictionaryRef)opts);
if (src)
{
CGImageRef img = 
CGImageSourceCreateImageAtIndex(src,0,(CFDictionaryRef)opts);
CFRelease(src);
if (img)
{
sig = [self signatureForImage:img];
CGImageRelease(img);
}
}
return sig;
}

// Here's the signature creation code...

- (ImageSignature*)signatureForImage:(CGImageRef)img
{
// Create a CIImage by passing the image through our filter chain.
CIImage *ciImage = [self filteredImage:(CGImageRef)img];

// Create a bitmap and paint our CIImage into it.
NSBitmapImageRep *inBmpImgRep = [[[NSBitmapImageRep alloc] 
initWithCIImage:ciImage] autorelease];
NSInteger pixelsWide = [inBmpImgRep size].width;
NSInteger pixelsHigh = [inBmpImgRep size].height;
NSInteger samplesPerPixel = 4;
NSBitmapImageRep *bmpImgRep = [[[NSBitmapImageRep alloc] 
initWithBitmapDataPlanes:NULL
  pixelsWide:pixelsWide pixelsHigh:pixelsHigh 
bitsPerSample:8
  samplesPerPixel:samplesPerPixel hasAlpha:YES 
isPlanar:NO
  colorSpaceName:NSDeviceRGBColorSpace 
bitmapFormat:0
  bytesPerRow:0 bitsPerPixel:0] autorelease];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext 
graphicsContextWithBitmapImageRep:bmpImgRep]];
[inBmpImgRep draw];
[NSGraphicsContext restoreGraphicsState];

// Create an ImageSignature and paint our bitmap into it.
ImageSignature *sig = [[[ImageSignature alloc] initWithSize:[bmpImgRep 
size]] autorelease];
float *buffer = [sig allItems];

// Signature creation snipped - it's a simple mapping of pixels to a float 
array

return sig;
}

// The images are pre-processed via some CIFilters...

- (CIImage *)filteredImage:(CGImageRef)img
{
// This method takes a CGImage and creates a filtered/scaled CIImage from 
it.
NSInteger srcWide = CGImageGetWidth(img);
NSInteger srcHigh = CGImageGetHeight(img);
CIImage *ciImage = [CIImage imageWithCGImage:(CGImageRef)img];

// Blur the image to smooth out the repeating noise from electronic 
interference.
CIFilter *discBlur = [CIFilter filterWithName:@"CIDiscBlur"];
[discBlur setDefaults];
[discBlur setValue:ciImage forKey:@"inputImage"];
[discBlur setValue:[NSNumber numberWithFloat:blurRadius] 
forKey:@"inputRadius"];
ciImage = [discBlur valueForKey:@"outputImage"];

// Other filters (scaling, edge detection, etc) snipped...

// We don't need pixels around the periphery, crop it.
CIFilter *cropROI = [CIFilter filterWithName:@"CICrop"];
[cropROI setDefaults];
[cropROI setValue:ciImage forKey:@"inputImage"];
CIVector *roiVector = [CIVector vectorWithX:roi.origin.x Y:roi.origin.y 
Z:roi.size.width W:roi.size.height];
[cropROI setValue:roiVector forKey:@"inputRectangle"];
ciImage = [cropROI valueForKey:@"outputImage"];

return ciImage;
}

Have I set up my caching policy (kCGImageSourceShouldCache) incorrectly?
I tried supplying a BOOL wrapped in an NSNumber but that made no difference.

This project is for Mac OS X 10.6 - I have no need to support anything earlier.

Stuart
___

Cocoa-dev maili

Re: Losing my memory - a caching problem?

2010-08-17 Thread Stuart Rogers
On 17 Aug 2010, at 18:05, Ken Ferry wrote:
> 
> (1) I would focus your attention on CoreImage in this case.
> (2) It is wonderful that you realized that if you want the bits in a specific 
> pixel format then you need to draw them in a bitmap, but you now have a 
> redundant bitmap:

Yes, I wanted to be sure I knew exactly what my bitmap format looked
like.  And yes again, I realised there was some redundancy there - I
wasn't quite sure at the time I wrote it how to avoid that.

> You can directly draw the CIImage in the context created from the bitmap.  
> 
> This by itself is not likely to be your problem, but fixing this may have a 
> side effect that fixes the problem.  When you use -[NSBitmapImageRep 
> initWithCIImage:], it basically calls -[CIContext createCGImage:fromRect:] 
> using -[NSGraphicsContext CIContext].  The latter is possibly a long lived 
> object, and the CIContext may be the location of caches.  

I think we're on the right track.  I've cut out the redundant bitmap and
although the problem remains, it's noticeably reduced.  (One of my test
sets contained 3500 images - previously it would chew through all 8GB,
but with my replacement code I have over 2.5GB left with no extra swap
files.  This isn't good enough, but it's a good start.)

My bitmap code now looks like this:

NSInteger pixelsWide = [ciImage extent].size.width;
NSInteger pixelsHigh = [ciImage extent].size.height;
NSInteger samplesPerPixel = 4;
NSBitmapImageRep *bmpImgRep = [[[NSBitmapImageRep alloc] 
  initWithBitmapDataPlanes:NULL
  pixelsWide:pixelsWide pixelsHigh:pixelsHigh 
bitsPerSample:8
  samplesPerPixel:samplesPerPixel hasAlpha:YES 
isPlanar:NO
  colorSpaceName:NSCalibratedRGBColorSpace 
bitmapFormat:0
  bytesPerRow:0 bitsPerPixel:0] autorelease];
[NSGraphicsContext saveGraphicsState];
NSGraphicsContext *ctx = [NSGraphicsContext 
graphicsContextWithBitmapImageRep:bmpImgRep];
[NSGraphicsContext setCurrentContext:ctx];
[[ctx CIContext] drawImage:ciImage atPoint:NSMakePoint(0,0) 
fromRect:NSMakeRect(0,0,pixelsWide,pixelsHigh)];
[NSGraphicsContext restoreGraphicsState];

The documentation for -[NSGraphicsContext CIContext] says that the CIContext
only lives for as long as its owning NSGraphicsContext, so I'm assuming (!) that
it'll be released when I pop the owning context with -restoreGraphicsState.

> (Also, it's unlikely that you want device RGB as the colorspace for the 
> bitmap.  If you want your results to be independent of the machine they're 
> produced on, you need to be using device-independent colorspaces.)

You're right - that was sloppy cut-and-paste on my part.  I'm a bit hazy
on colour spaces, but I've switched it to NSCalibratedRGBColorSpace.

Thanks very much for your help, it's much appreciated.

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-17 Thread Stuart Rogers
On 17 Aug 2010, at 18:07, Ken Ferry wrote:
> On Tue, Aug 17, 2010 at 9:53 AM, Cem Karan  wrote:
> 
>> One dumb question; I see where you're putting images into an autorelease 
>> pool, but I don't see you setting up or tearing down pools.  Where are you 
>> doing that?
> 
> Or, it could be much easier than I was saying and you might just need an 
> autorelease pool.

Good question, but I had that covered - here's my main loop code
(with error handling snipped):

for (NSString *path in self.paths)
{
// SNIP: User-initiated break-out check

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ImageSignature *sig = [self.net.factory signatureForPath:path];
if (sig)
{
self.step = self.step + 1;
[self.net feedforward:sig];
[self processResponseForPath:path];
}
[pool release];
}

This all runs in the background via dispatch_async().

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-17 Thread Stuart Rogers
On 17 Aug 2010, at 21:36, Cem Karan wrote:
> On Aug 17, 2010, at 4:05 PM, Stuart Rogers wrote:
>> 
>>   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
>>   ...
>>   [pool release];
> 
> Have you tried using drain instead of release?  That seems to be the 
> preferred way at this point, triggering GC collection if needed (I don't know 
> if your code is GC enabled, but if the library code is GC enabled, then this 
> will solve some of those problems)

My app is uses retain/release - I have an aversion to garbage collection - so
(according to the documentation) drain will do exactly the same as release.

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-17 Thread Stuart Rogers
On 17 Aug 2010, at 22:48, Sean McBride wrote:
> On Tue, 17 Aug 2010 22:20:55 +0100, Stuart Rogers said:
> 
>>>>  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
>>>>  ...
>>>>  [pool release];
>>> 
>>> Have you tried using drain instead of release?  That seems to be the
>> preferred way at this point, triggering GC collection if needed (I don't
>> know if your code is GC enabled, but if the library code is GC enabled,
>> then this will solve some of those problems)
>> 
>> My app is uses retain/release - I have an aversion to garbage collection - so
>> (according to the documentation) drain will do exactly the same as release.
> 
> Still, using drain is probably a good habit to get into.  For example,
> the clang static analyzer flags using release on an autorelease pool as
> a warning.

Really?  For me, after a clean build, Build & Analyse doesn't complain.
What warning do you get?

Stuart, Xcode v3.2.1 on OSX 10.6.4

___

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

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


Re: Losing my memory - a caching problem?

2010-08-18 Thread Stuart Rogers
On 18 Aug 2010, at 01:26, Shawn Erickson wrote:
> 
> ... however if your application loads
> file data (aka image data in your case) only once or it is unlikely
> your application will load the same file data again in the reasonable
> near future then you should look at disabling file caching of the file
> data you load.
> 
> Review...
> 
> http://developer.apple.com/mac/library/documentation/Performance/Conceptual/FileSystem/Articles/FilePerformance.html#//apple_ref/doc/uid/20001987-99732
> 
> I don't think "kCGImageSourceShouldCache" affects caching at the file
> system cache level, it only enables/disables cacheing of decoded image
> data (aka raw pixels instead of source jpeg data). To avoid file
> caching you may have to load file data in a different way...

Yes, it did occur to me that I was locking the stable door after the horse
had bolted.  Thanks for the pointer - I think disabling file caching might be
an approach worth pursuing (although the man page for fctrl isn't yet
making much sense to me).

> I would consider asking this question on the quartz developer list.

Will do, but I think I'll play with Instruments and file caching first.

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-18 Thread Stuart Rogers
On 18 Aug 2010, at 01:31, Ken Thomases wrote:
> On Aug 17, 2010, at 7:26 PM, Shawn Erickson wrote:
> 
>> When you say "free" I assume you mean the "free:" number listed in
>> activity viewer for the system as a whole?
> 
>> If so then what you are seeing is an expected result of the "unified
>> buffer cache" maintained by the system (since you say private memory
>> of your application doesn't increase). In a nut shell unused RAM is
>> wasted RAM so the system always attempts to cache once used pages of
>> memory (for example file data loaded by your application) as long as
>> possible until they need to be reused for active / new allocations.
> 
> In an even smaller nutshell: you should consider Inactive as equivalent to 
> Free in Activity Monitor's System Memory tab.

I quite understand this, but the practice doesn't quite fit the theory.
If 'inactive' is effectively available as 'free' for all apps, then it should be
available to my app.  And yet, when 'free' drops to just a few megabytes
I see extra swap files being created despite there being several gigabytes
available as 'inactive', which suggests to me that the unified buffer caching
is too aggressive - the cache is being maintained at the expense of swap
files.

Now, one or two swap files on this machine (an i7 iMac) isn't the end
of the world - I don't really notice any system sluggishness until I get
more than three swap files.  But as the target for this software will likely
be a low end Mac, this is a concern - on my 2GB Core Duo MBP this
code will kick off so many swap files the machine becomes barely useable.

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-18 Thread Stuart Rogers
On 18 Aug 2010, at 06:57, Ken Ferry wrote:
> 
> Did you say that the Object Alloc tool does not report the memory that is 
> being used?  First verify that.  You don't want to use the object alloc tool 
> from the leaks template, its config options are not appropriate.  Start from 
> the "Allocations" template.
>> 

I must admit I'm a little lost with Instruments - I only really understand it in
a vague, arm-waving way.

The object alloc tool in the Leaks template seems to remove old allocations
from the graph when (I assume) those memory blocks are released, so its
trace is mostly blank beyond an initial spike or two and a short running trail
that follows the 'play head'.

The ObjectAlloc template results is different, and I'm not quite sure what I'm
looking at.  I can see allocations occurring at specific events (launch, switch
to test mode, select source files, and start) but I don't understand what's
going on beyond my 'start' phase - I see allocations rising for a few seconds
and then flattening off, but my code isn't doing anything different at that
point.  Each test cycle is identical, taking about 15ms - there's no different
code path after a few seconds.

Assuming I've got my sharing settings right, there should be a screen grab
at 

> If that fails, this suggests that the memory is allocated in an exotic way.  
> Instruments will catch malloc'd memory, but not mmap'd memory or direct calls 
> to vm_allocate.  

If anything exotic's going on, I'm pretty sure it's not directly of my doing!
My code mostly uses standard Obj-C alloc/init, with a smattering of malloc,
but definitely no mmap or vm_allocate.

> You can try using tools like /usr/bin/vmmap and /usr/bin/allmemory to try to 
> see where the memory is going.  If it really is exotic, though, it's probably 
> CoreImage.  Last I was aware there _was_ some global caching in CoreImage 
> that was too aggressive in some circumstances, but things may very well have 
> changed.

Thanks for the pointers.  This might take me a while as this is taking me
into unchartered territory.  This, along with Shawn Erickson's suggestion
of disabling file caching, has given me plenty to start thinking about.

Stuart

___

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

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


Re: Losing my memory - a caching problem?

2010-08-18 Thread Stuart Rogers
On 18 Aug 2010, at 01:26, Shawn Erickson wrote:
> 
> So in general you shouldn't worry about free RAM shrinking to a sliver
> of total system RAM over time... however if your application loads
> file data (aka image data in your case) only once or it is unlikely
> your application will load the same file data again in the reasonable
> near future then you should look at disabling file caching of the file
> data you load.

I think we have a winner!  I've just implemented Shawn's suggestion
and it seems to solve my problem.  I've just passed 9,695 image files
through my code's test phase (at 1.2MB apiece, that's over 11GB of
data) and I still have over 6.4GB marked as free.  I am a very happy
bunny!

(That's not to invalidate Ken's suggestion that CoreImage is caching
stuff - each time I run my test I'm losing a little more memory, but it's
on the level of noise compared to turning off file caching.)

Thanks very much to everyone who contributed to this!

For the record, my non-caching code looks like this (error handling snipped):

- (ImageSignature *)signatureForPath:(NSString *)path
{
ImageSignature *sig = nil;
NSData *data = [NSData dataWithContentsOfFile:path options:NSUncachedRead 
error:nil];
NSDictionary *opts = [NSDictionary dictionaryWithObject:(id)kCFBooleanFalse
   
forKey:(NSString*)kCGImageSourceShouldCache];
CGImageSourceRef src = 
CGImageSourceCreateWithData((CFDataRef)data,(CFDictionaryRef)opts);
if (src)
{
CGImageRef img = 
CGImageSourceCreateImageAtIndex(src,0,(CFDictionaryRef)opts);
CFRelease(src);
if (img)
{
sig = [self signatureForImage:img];
CGImageRelease(img);
}
}
return sig;
}

Stuart
___

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

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


Re: Cocoa bindings and reluctance to use NSPopupButon

2008-05-19 Thread Stuart Rogers

David <[EMAIL PROTECTED]> wrote:


So, I'm realizing that maybe its more reasonable to back down to
just using a data source, target/action and delegates.


Don't think of it as backing down; think of it as using a more appropriate
technology.  (For some appropriate definition of 'appropriate' of course.) 


I'm still having trouble understanding the delegate signatures when
they throw in some (id) types, I'm not sure what data types are
expected.


You don't need to know.  All that's needed is that the delegate implement
certain methods.  See the reference docs for the class that uses the
delegate for the expected methods - they're usually listed at the end
of the class's list of tasks, and are usually flagged as required or
optional. 

Stuart 


___

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

This email sent to [EMAIL PROTECTED]


Re: Storing values in dictionary with their address as the key

2008-07-29 Thread Stuart Rogers


If I wanted to store an object in a dictionary and set its key as  
the

object's memory address - how would I go about doing this?


I'm racking my brains trying to think of a good reason to do this  
and am

drawing a blank. I can, however, think of myriad bad reasons.


 Agreed - I can't help but wonder about class clusters but I can't
think of a direct reason why this would be a 'problem area'. It's just
the first thing that popped into my head. :-)


Maybe I'm misunderstanding, but this strikes me as a clunky way
of implementing a set.

Stuart

___

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

This email sent to [EMAIL PROTECTED]


Re: Need to override +(Class) class?

2008-09-28 Thread Stuart Rogers

On 28 Sep 2008, at 10:02, Dave DeLong wrote:


I'm building an app, and I've got a bunch of interface object
definitions called "InputElements".  There are a couple subclasses,
such as InputElementButton and InputElementSlider.

I'm building the interface via an "InputMode" object, that contains an
array of InputElement objects.  As I build the interface, I loop
through the InputElement objects in the InputModes array, and am doing
the following:

for (InputElement * element in [inputMode elements]) {
if ([element isKindOfClass:[InputElementButton class]]) {
//build an InputViewButton
} else if ([element isKindOfClass:[InputElementSlider class]]) {
//build an InputViewSlider
}
}


As an aside...  If InputElementButton and InputElementSlider had a
common superclass, and InputViewButton and InputViewSlider had a
common superclass, you could simplify your code along the lines of:

for (InputElement * element in [inputMode elements])
{
InputView *inputView = [element buildInputView];
// ...
}

...where -buildInputView is declared by the InputElement superclass
and overridden by the subclasses as necessary, returning a suitable
InputView subclass.

Of course you might have good reason to know the class at run time,
but in most cases I've come across (in my limited experience) there's
usually a simpler approach that avoids it.

Stuart

___

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

This email sent to [EMAIL PROTECTED]


Re: Arggg...overrelease in table view cell, but where?

2008-12-11 Thread Stuart Rogers



I have implemented -copyWithZone in my NSTFC subclass as such:

- (id)copyWithZone:(NSZone *)zone
{
 MyTableCell*copy = [super copyWithZone:zone];
 copy.cellObject = [self.cellObject copy];
 copy.gridController = [self.ViewController copy];

 return copy;
}


NSCells use NSCopyObject to do their copies, which ends up setting the
values of cellObject and gridController in your copies, but not
retaining them. You need to nil them out before setting the values in
your properties. This is a long-standing misbehavior of NSCell that
probably won’t be changing anytime soon.


Just in case Corbin misses the opportunity to reference it yet again,
see ImagePreviewCell.m in:



Stuart

___

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

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