Is there a way to inspect an NSAutoreleasePool's objects? - objective-c

Just wondering if this is even possible, maybe I could retrieve an NSSet of objects that are currently stored in a given NSAutoreleasePool instance?
I have looked through Apple's NSAutoreleasePool reference and have not found much pertaining to this question.

If the purpose is just for debugging, you could use the function _CFAutoreleasePoolPrintPools() to print the content of the pool, as documented in TN2124. It is available since Mac OS X 10.6 and iOS maybe since 3.x.
Alternatively, the class method [NSAutoreleasePool showPools] performs the same action.

No, there is not. The implementation details of NSAutoreleasePool are deep black magic.
What you might do instead is to make your own autorelease pool and somehow fool the runtime into thinking that it should use your pool instead of NSAutoreleasePool. But only do this for the thrill of trying it.
HOWEVER, YOU SHOULD NEVER ALTER AUTORELEASE BEHAVIOR FOR ANYTHING OTHER THAN EXPERIMENTATION AND LEARNING. OTHERWISE I WILL FIND YOU. AND MAKE YOU REWRITE YOUR CODE.

Related

Memory Management in a Objective-C static library

I'm quite new to the Objectivce-C and I was wondering what is the correct way of memory management in a static library without ARC.
Lets say my library has a method that returns NSString*:
- (NSString *) foo
{
...
NSString *result = [[NSString alloc] initWithString:#"bar"];
return [result autorelease];
}
So as far as I understand, since foo allocated the NSString it also needs to release it (or queue it for releasing). NSString is a return value, so the only thing I can do is to autorelease it. This creates a problem: if library is used in a command line tool, the developer needs to know that foo needs an #autoreleasepool otherwise calling foo multiple times inside main #autoreleasepool with eat up memory. This seems to me like I'm delegating memory management from library to the app which seems like a terrible thing to do. Is there a better way to do this? Or can I somehow make it obvious for the developer that foo needs an #autoreleasepool?
Autorelease pools do not deallocate objects automatically; they need to be manually drained. In Cocoa applications, this is done by the main thread's run loop, so normally most of developers don't have to do anything for that and don't know about it.
However, in any long-running functions, like command-line tool's main, or a background thread, it's the programmer's responsibility to manually drain autorelease pool periodically.
You are following the global memory management rules and that's the right thing to do. There's no need to change anything; it's not about ARC or static libraries.
Every thread requires an autoreleasepool*. If your code is called and there is no pool in place then the thread hasn't been set up properly and this is a programmer error.
Unless you created the thread (or process) this isn't your responsibility and has nothing to do with lazy memory management on your behalf.
The reason methods don't indicate that they need an autoreleasepool to be in place is because an autorelease pool always has to be in place.
*Sure you can write Objective-c that doesn't use autorelease, and about which you can reason with almost certainty will never use autorelease when internals change. Such code would only be able to use a small subset of Cocoa, if any, and would likely be pretty terrible.

Getting callbacks of FSPathCopyObjectAsync in ARC

I'm looking to use FSPathCopyObjectAsync and I'm failing. In order to get my head around the problem I've been looking for examples of it elsewhere and although I was experimenting with the slightly dated source code from Matt Long's tutorial over on Cocoa is my Girlfriend, I then found a bit more elaborate example in a project on github, as a category on NSFileManager. Since my project is running under ARC, I tried porting it, and succeeded only at the half of it.
In its current form, the actual copying works, yet the callback method MZCopyFSPathFileOperationStatusProc is never called. That callback method happens to be the sole reason for using asynchronous copying, otherwise one might as well run a synchronous one in the background. I'm assuming the reason for the callback not being called is that some object is incorrectly released by ARC, but there could be something else going on. I am holding on to the return object of the copyItemAsyncAtPath:toPath:destName:options:statusChangeInterval:error: method, so that can't be it, right?
Who can spot the error and explain why this category isn't generating any callbacks? Is it ARC? Is it something else?
Much obliged. EP.
P.S. For redundancy reasons, here is the gist: https://gist.github.com/6f3715753896ccf6fd35
Your delegate needs to be strongly referenced by something. NSFileManager will only hold a weak reference to it (as it should do), so if you don’t have a strong reference to it, your delegate will get released and the callbacks won’t be seen.
Have you considered using blocks for the callbacks? That would probably be preferable.

Why #autoreleasepool?

Under ARC, we can no longer call autorelease. Essentially, the entire notion of auto release pool is out the window. Why then, do we need the #autoreleasepool directive?
In fact the notion of retain/release/autorelease is still present when using ARC. The difference is that the compiler adds them for you. This means that the concept of an autorelease pool is still relevant and you might want to use them in exactly the same situations as before.

Confused about Xibs and programmatically

i a newbie for iphone development. I got some questions here.
I know IB is a convinience tool for UI desgin and you also can do most things programmatically. I am just wondering, when should I create an interface controll without IB and why so. I am trying to form a good habit for this. Thank you very much. A friend told me that when efficiency should be considered for the application, then i should create interface controller programmatically, any other cases?
I am studying Learn Objective c on Mac now. It says that "Apple suggests you avoid using autorelease on your own code". So, does it mean I cannot use "autorelease" or just i should avoid using it. For example, can i use following code in my own code for iphone development?
#Interface Test {
A* a;
}
#Implementation {
a = [[[A alloc]init]autorelease];
}
Thank you for your time to read this. I am looking forward to answers :D.
Sometimes creating custom controls will require you to build them programmatically.
No, it's not that you can not use autorealease, it's just that using it adds to the burden of memory management. But in some cases you probably don't have an option, such as when you have a method that returns a temporary object. Using retain/release method to manually control object lifespan is the recommended way of doing things in iPhone development. Please see Autorelease pool for more details.
See Matt Gallagher's blog post for a discussion of efficiency. Simply put, one method is probably no more efficient than the other. This depends on your specific application, of course. Generally speaking, do what is most comfortable in designing your user interface. Make optimizations as needed.
1) If you are doing basic views that interface building has the widgets ready to go for, then use interface builder, it will make your life easier. Plus if you are just starting out it will let you get some sample code out the door faster. I'm not a huge fan of interface builder, but if you have to maintain code, you'll come across it so good thing to get familiar with it.
2) I don't think that autorelease is a bad thing. If you are writing single threaded code there is not as much to worry about. However, the thing that can come back to bite you is that you don't actually know when things will be released. So if you have programmed poorly, and try to reference an object that you have autoreleased later in code then you may get inconsistent behavior. I autorelease, but I also am very good about retain/release in other parts of my code that is passed these objects.

NSBlockOperation and NSAutoreleasePool

Normally when you create an NSOperation subclass you are responsible for creating and releasing an NSAutoreleasePool in the -main method.
When you use an NSBlockOperation, do you need to create an autorelease pool in the block?
No. GCD (which NSOperationQueue is built on top of as of OS X 10.6 or iOS 4.2) manages autorelease pools for you, the same way that NSRunLoop does.
I don’t think so, as the work queues have their own pools already created for you.
Adam,
Your best bet is to read up on block memory behavior with objects. Here is the link for the iOS Blocks and Variables the bottom of this page has information regarding object types.
Frank