This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Does every thread need its own autorelease pool?
I would like to know why it is required to use autorelease pool, when we call some methods on a separate thread rather than the main thread, please clarify.
If you're using garbage collection EXCLUSIVELY in the thread you don't need an autorelease pool for it.
However, if you're manually managing retain counts (managed memory model) at all, even if you're using it with garbage collection as well, then each thread DOES need it's own autorelease pool.
Autorelease pools are thread-specific, that is a pool from thread A can't access/manage a pool from thread B. Typically each thread will have multiple autorelease pools to lessen memory usage. Again, nested pools are specific to their thread - they can't manage memory from other threads.
You should read up on the the iOS threading guide at https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/
Also, Apple is recommending migrating away from threading and managing concurrency with Grand Central Dispatch. It's a fair bit easier to do, IME, for anything complicated:
https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW1
I think I don't get your question. Anyway you could google it what it does or for what its needed or read a book on ios development ;)
The autoreleasepool handles all your memory issues, when you are using ARC (Automatic Reference Counting). So you dont need a void dealloc method to do it and release everything at the hand manually.
This goes for main, as for seperates thread inside your app. The autoreleasepool takes care of all of them.
Hope that answers your question. Short, but simple.
Related
I have a question. My case study is that I have two big SQLite databases and I want to use threads (meaning 2 processes simultaneously). Did it work well? I have written the following code:
NSAutoreleasePool *dbPool;
dbPool = [[NSAutoreleasePool alloc] init];
/* All Database work is performed here */
[dbPool release];
Please guide me. Am I doing this correctly or not? Should I use a pool to drain or release?
And in that way is this using concurrent processes, meaning it's also the same behavior as multitasking?
Thanks in advance!
Yep, you're doing it right. Each of your new thread needs own autorelease pool.
Regarding to your question about release / drain of pool, recommended is drain message.
What do you mean by sqlite database? How do you access it? If you access it via CoreData, you have keep following in your memory:
you need one NSManagedObjectContext per thread,
do not pass NSManagedObjects to another thread, just pass object ID,
before you pass object ID to another thread, save it in thread where it was modified / created before passing it.
There are more rules, but these are basic ones.
Multitasking means that you can run more applications in one time. Multithreading (= your case) means that your application does use more threads to achieve its task.
A common approach for user interface or other heavy object management work is to surround your code like you're doing, but you should be using drain:
NSAutoreleasePool *dbPool = [[NSAutoreleasePool alloc] init];
// do your work
[dbPool drain];
A lot of detail on NSAutoreleasePool is available here and a previous Stack Overflow answer here. Basically the work you're doing inside the pool, if set to autorelease, will be released once the pool drains. This can increase performance when working with certain classes that produce autoreleased instances. If you want full and immediate control though, you can release each object you're working with once it's no longer needed and ditch the pool altogether.
As to your multithreading questions I'm not sure if I understand what you're asking but nonetheless using the pool is a solid approach even in a background thread. This is assuming that the objects you're working with in the thread aren't somehow also used in another (since you might have an accidental release).
I have some simple doubts about NSOperation and GCD that I have not found answer to on the documentation.
The firs question is related to memory management:
I want to know if I need to create an Autorealease pool for the methods I wil add to the NSOperationQueue; similarly to when you run a method on different thread without NSOperations.
The next question is whether NSOperation takes care of GCD or if this needs to be done manually?
Thank you for your help!
I just saw your question here and there is a post on the apple dev forums you might be interested in. According to one of the apple guys on this thread so long as you run your NSOperation through an NSOperationQueue you do not need to create your own autorelease pool as the NSOperationQueue does it for you.
Also the docs for NSOperationQueue apparently need to be updated/corrected. On devices running iOS 4 or later NSOperationQueue does use GCD despite what the class reference documents say.
According to the documentation, you should create an NSAutoreleasePool in the main method of your NSOperation. The documentation for NSInvocationOperation and NSBlockOperation doesn't specify whether they create an autorelease pool for you, so to be safe it would be best to create one when using those classes too.
The NSOperationQueue handles queuing and executing the operations, so you shouldn't have to mess with GCD yourself for tasks related to the operation queue.
I don't use thread explicitly, so when designing an iPhone app, e.g. using Singleton, should I need to take care of the thread issue?
Beware of a singleton being called by or using any OS classes that could become multi-threaded on future multi-core hardware. Also beware of forgetting that this class isn't thread safe N years from now, reusing it, and wasting your life hunting the bug.
If not, no.
In the most part you should be safe, but I would be aware that even if you don't use threads explicitly, there are many libraries in the Apple SDK that have asynchronous callbacks (such as HTTP requests) where you will need to synchronize access across shared memory.
I hope this helps!
I currently have implemented a third party library into my XCode project. The problem is that there are memory leaks which originate from the library which I found using Instruments.
My question is is it possible to kick off the API function which is leaking in a separate thread using the autorelease pool in order for that thread to clean up after itself? This way when I need to use it again, I start the function call in a different thread? In essence my thought is that it would be garbage collecting the leaky code so that it doesn't impact the main executable.
Memory leaks will be present either in the main thread or in any other thread. What's the difference between autoreleasing a leaking memory or releasing a leaking memory?
Same effect!
Fix the leaks.
Cheers
Coming up towards the end of developing an iPhone application and I'm wondering just how bad is it to use autorelease when developing for the iphone. I'm faced with some fairly random crashes and, so far, I can't pinpoint it to anything other than sloppy memory usage.
As a Cocoa newbie I remember initially reading a guideline document that strongly suggested avoiding autorelease in favor of manual retain/release for iPhone. However, a more 'senior' Cocoa developer came on board early on (who ironically has been let go since), who used autorelease all over the place. Admittedly, I was went into "monkey see monkey do" mode, and it appears to be coming back to haunt me (I'm now the only developer on the project).
So what to do next? It seems to me that I have to branch the code and try to go through and replace, where possible, autorelease code keeping my fingers crossed that I don't inadvertently break the app. It seems a lot of library calls result in autoreleased objects like stringWithFormat and pretty much anything where I'm not using alloc myself. Any other gotchyas and/or suggestions I should be looking out for? Thanks Cocoa gurus.
Using release instead of autorelease can improve memory usage in tight spots (which is good on the iPhone), but it's not going to help at all with crashing if you're not following the retain / release rules. I would read a few tutorials on memory management in Obj-C if you're still a little hazy on what you should be doing, and then go after those crashes using the debugger and crash reports to find out where you're over releasing objects. This and this are two good places to start.
More important than the autorelease or manual-release choice is how often you alloc and dealloc your NSAutoreleasePools. Since most of the Cocoa frameworks use autorelease liberally, you need to have a proper pool draining strategy. Once that is in place, the choice of whether to release or autorelease becomes much less an issue.
That being said, the only areas you should worry about are tight loops--allocate and release an NSAutoreleasePool every few iterations for best results; and when you have spawned another NSThread that doesn't have a Runloop--create a pool and drain it every so often becomes idle. Since most applications only allocate a small amount of data per event, UIKit's strategy of allocating the pool before the event is dispatched and releasing it after the dispatch returns works very well.
If you think you dunno how to use autorelease, check out CS193p FALL 2010 on iTunes U -> Lecture number 4.
It teaches you all about memory management and stuff (if you skip the first 10 minutes or so)
For iPhone performance reasons, Apple suggest that, whenever possible, you shouldn't use autoreleased objects. Instead, explicitly release your objects when you are done with them.
Using autorelease pools means that you might be leaving some unused memory lying around. Since the iPhone has less memory to go around, you might improve performance if you free up unneeded memory as soon as possible, rather than letting it sit around taking up resources while it waits for an autorelease.
When you autorelease, you're basically saying: "I don't need this any longer, but anyone else is free to pick it up (before the auto release pool is drained)". When you explicitly relase an object you're saying: "I don't need this any longer and unless anyone else has already said otherwise (acquired), it should be deallocated immediately."
Consequently, autorelease is not normally the wrong thing to. It is required when you want to pass objects back to the sender of a message without requiring the sender to take care of releasing the object.