0

What is the non-autorelease equivalent of this code?

NSString *nsFName = [[NSBundle mainBundle] pathForResource:nsName ofType:nsExt inDirectory:nsPath];

CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74
  • Why don't you have an autorelease pool in place? There should always be a top-level pool in Cocoa. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html – jscs May 28 '12 at 04:41
  • this code is running on a separate thread – CuriousGeorge May 28 '12 at 04:47
  • You should be setting up your own pool, then. http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW16 – jscs May 28 '12 at 04:48
  • In my case, these threads don't last long, and may be spawned in large numbers...in that case, wouldn't it be wasteful creating autorelease pools for every one? – CuriousGeorge May 28 '12 at 04:54
  • You should probably be looking into alternatives to explicit thread use, then; at this point they are a tool of last resort in Cocoa. Take a gander at the [Concurrency Programming Guide](http://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/); it sounds like using a GCD queue would suit your needs. – jscs May 28 '12 at 04:57
  • unfortunately, this isn't just for cocoa. It's c++ code that has to maintain an interface compatible with android/windows as well – CuriousGeorge May 28 '12 at 04:59
  • Then you have to set up a pool. There's no way around not having an autorelease pool per thread if you're using Cocoa; even if _you_ don't use any methods that create autoreleased objects, internal code may. – jscs May 28 '12 at 05:01
  • ok. I think I may be confused though...does the autorelease pool actually allocate any memory up front? or is it just objective-c's way of handling something like a c++ shared_ptr? – CuriousGeorge May 28 '12 at 05:06
  • An autorelease pool is an object, yes, although with the latest few compilers it's private, and we just use `@autoreleasepool{//code here}`. It maintains a list of objects (that it owns), and sends `release` to each of them when it is drained. – jscs May 28 '12 at 05:08
  • awesome, thanks. I Thought the autorelease pool was pre-allocating a fixed amount of memory every time, not just storing a bunch of references to things that need to be destroyed. – CuriousGeorge May 28 '12 at 05:25

1 Answers1

3

There isn't one. When you're using Cocoa, you must have a pool in place:

Cocoa always expects there to be an autorelease pool available. If a pool is not available, autoreleased objects do not get released and your application leaks memory. If you send an autorelease message when a pool is not available, Cocoa logs a suitable error message.

Part of the GUI application set-up process is establishing one on the main thread; non-GUI programs need to create one as well.

If you're creating your own threads, you need to create and manage an autorelease pool for each of those threads as well:

Applications that link in Objective-C frameworks typically must create at least one autorelease pool in each of their threads. If an application uses the managed model—where the application handles the retaining and releasing of objects—the autorelease pool catches any objects that are autoreleased from that thread.

Depending on what else you are doing, you may be able to use CoreFoundation. There's a CFType, CFBundle, on which NSBundle is built. It has a function CFBundleCopyResourceURL() that may do what you need. If you can translate all your code to Core Foundation, then you can escape using a pool, although -- as Ken says -- it's really not the burden that you think it is. You're probably hitting the disk every time you use pathForResource:ofType: anyways.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • 3
    +1 and I'll add that concerns about the "expense" of setting up and tearing down an autorelease pool are misplaced. They're just [not that expensive](http://www.mikeash.com/pyblog/autorelease-is-fast.html) and are even cheaper now with `@autoreleasepool`. The cost is surely dwarfed by even `-[NSBundle pathForResource:ofType:]` let alone creating and tearing down **threads** "in large numbers"(!). – Ken Thomases May 28 '12 at 05:05