Objective C - Where do you dealloc global static variables? - objective-c

Or, what is the opposite of +(void)initialize?
Here's my situation:
I have a class Unit, whose -(id)initWithName: function takes data from a global NSDictionary, which is created lazily, defined in the Unit.m file as:
static NSMutableDictionary *unitLibrary = nil;
Where do I call [unitLibrary release]?

You can call it at a location in which you know the dictionary is not needed anymore. If it is needed throughout the entire lifecycle of the application, then you don't have to do anything as all memories will be reclaimed by the OS when the app terminates.

There's no general-purpose answer. You should deallocate it when you're sure it won't be used again. Possible candidates might be in the applicationWillTerminate delegate message, or through an atexit() function.

Related

Why there is no leak in Grabkit

Grabkit is a Drop-in iOS component to easily import photos from Facebook, FlickR, Instagram, Picasa
In Grabkit, a GRKXXXQuery is a wrapper that transform a delegate based query to block based query.A GRKXXXGrabber is a block based class that use GRKXXXQuery to grab photos from a cloud service.
Take GRKFlickrXXX for example. GRKFlickrGrabber has a NSMutableArray that stores Queries(in super class GRKServiceGrabber). And in method albumsOfCurrentUserAtPageIndex:withNumberOfAlbumsPerPage:andCompleteBlock:andErrorBlock:, a query(GRKFlickrQuery) was created and stored in the NSMutableArray by calling registerQueryAsLoading:. The query takes blocks as params and in GRKFlickrQuery these block are stored as instance variables. And there is self in these blocks
Simply: GRKFlickrGrabber -> NSMutableArray(_queries) -> GRKFlickrQuery(query) -> block -> GRKFlickrGrabber(self)
So there is a retain cycle here. But when I profile the Grabkit Demo using instruments, there is no leak. Did they use some tricks that break the retian cycle ?
A retain cycle is only problematic if you expect the Block that has a strong reference to an object to be deallocated during that object's deallocation. If the Block is destroyed for some other reason, before then -- such as after the query has run -- the cycle will be broken.
A retain cycle does not neccessarily lead to a leak. It is only a leak, when you expect the objects to be cleaned-up in dealloc (including "automatic" dealloc of ARC). If you clear the block property say at the end of a async request manually, it works fine.

Retaining/Copy Block Arc [iOS]

I have seen a lot of answers around, but I couldn't find any solution for my problem.
I basically have a Class where I only use class methods. I never allocate this class. So, I am passing a block to it and storing it on a static on the .h of the class, like this:
static ErrorBlock _errorBlock;
I am storing this way:
_errorBlock = [errorBlock copy];
I receive errorBlock as a parameter of a method. After some calculations, I invoke the block like this:
_errorBlock(error);
It's worth saying that I am invoking this from a Class's Category. The application basically returns:
EXC_BAD_ACCESSS(code=2, adress = 0xc)
When I check the _errorBlock value, it's nil. So my question is, how can I keep a live reference to the block?
If _errorBlock is "nil" it might be safe to say that it was assigned with nil and there is no reference to keep it alive. If you create a reference as in NSObject *reference = someObject and someObject is released your reference pointer will still point to location where someObject used to be and should not be nil. Check if you have some problems with assigning the block or if it even gets called. Also you might want to check if _errorBlock exists before calling it.
I was able to work it out, my removing completely the use of global blocks. At the moment I use the blocks my passing them as parameters.

Passing blocks in Objective-C

When writing a method that accepts a block as an argument, do I need to do anything special such as copying the block to the heap before executing it? For example, if I had the following method:
- (void)testWithBlock:(void (^)(NSString *))block {
NSString *testString = #"Test";
block(testString);
}
Should I do anything with block before calling it, or when entering the method? Or is the above the correct way of using the passed-in block? Also, is the following way of calling the method correct, or should I do something with the block before passing it?
[object testWithBlock:^(NSString *test){
NSLog(#"[%#]", test);
}];
Where do I need to copy the block? And how would this have been different if I wasn't using ARC?
When you receive a block as a method parameter, that block could be the original that had been created on the stack or it could be copy (a block on the heap). As far as I'm aware, there's no way tell. So the general rule of thumb is if you're going to execute the block within the method that's receiving it, you don't need to copy it. If you intend to pass that block to another method (which may or may not execute it immediately) then you also don't need to copy it (the receiving method should copy it if it intends to keep it around). However, if you intend to store the block in any way for some place for later execution, you need to copy it. The primary example many people use is some sort of completion block held as an instance variable:
typedef void (^IDBlock) (id);
#implementation MyClass{
IDBlock _completionBlock;
}
However, you also need to copy it if you're going to add it to any kind of collection class, like an NSArray or NSDictionary. Otherwise, you'll get errors (most likely EXC_BAD_ACCESS) or possibly data corruption when you try to execute the block later.
When you execute a block, it's important to test first if the block is nil. Objective-c will allow you to pass nil to a block method parameter. If that block is nil, you'll get EXC_BAD_ACCESS when you try to execute it. Luckily this is easy to do. In your example, you'd write:
- (void)testWithBlock:(void (^)(NSString *))block {
NSString *testString = #"Test";
if (block) block(testString);
}
There are performance considerations in copying blocks. Compared to creating a block on the stack, copying a block to the heap is not trivial. It's not a major deal in general, but if you're using a block iteratively or using a bunch of blocks iteratively and copying them on each execution, it'll create a performance hit. So if your method - (void)testWithBlock:(void (^)(NSString *))block; were in some kind of loop, copying that block might hurt your performance if you don't need to copy it.
Another place you need to copy a block is if you intend on calling that block in itself (block recursion). This isn't all that common, but you must copy the block if you intend to do this. See my question/answer on SO here: Recursive Blocks In Objective-C.
Finally, if you're going to store a block you need to be really careful about creating retain cycles. Blocks will retain any object passed into it, and if that object is an instance variable, it will retain the instance variable's class (self). I personally love blocks and use them all the time. But there's a reason Apple doesn't use/store blocks for their UIKit classes and instead stick with either a target/action or delegate pattern. If you (the class creating the block) are retaining the class that is receiving/copying/storing the block, and in that block you reference either yourself or ANY class instance variable, you've created a retain cycle (classA -> classB -> block -> classA). This is remarkably easy to do, and it's something I've done too many times. Moreover, "Leaks" in Instruments doesn't catch it. The method to get around this is easy: simply create a temporary __weak variable (for ARC) or __block variable (non-ARC) and the block won't retain that variable. So,for example, the following would be a retain cycle if the 'object' copies/stores the block:
[object testWithBlock:^(NSString *test){
_iVar = test;
NSLog(#"[%#]", test);
}];
However, to fix this (using ARC):
__weak IVarClass *iVar = _iVar;
[object testWithBlock:^(NSString *test){
iVar = test;
NSLog(#"[%#]", test);
}];
You can also do something like this:
__weak ClassOfSelf _self = self;
[object testWithBlock:^(NSString *test){
_self->_iVar = test;
NSLog(#"[%#]", test);
}];
Note that many people don't like the above because they consider it fragile, but it is a valid way of accessing variables.
Update - The current compiler now warns if you try to directly access a variable using '->'. For this reason (as well as reasons of safety) it's best to create a property for the variables you want to access. So instead of _self->_iVar = test; you would use: _self.iVar = test;.
UPDATE (more info)
Generally, it's best to consider the method that receives the block as responsible for determining whether the block needs to be copied rather than the caller. This is because the receiving method can be the only one that knows just how long the block needs to be kept alive or if it needs to be copied. You (as the programmer) will obviously know this information when you write the call, but if you mentally consider the caller and receiver at separate objects, the caller gives the receiver the block and is done with it. Therefore, it shouldn't need to know what is done with the block after it's gone. On the flip side, it's quite possible that the caller may have already copied the block (maybe it stored the block and is now handing it off to another method) but the receiver (who also intends on storing the block) should still copy the block (even though the block as already been copied). The receiver can't know that the block has already been copied, and some blocks it receives may be copied while others may not be. Therefore the receiver should always copy a block it intends on keeping around? Make sense? This essentially is good Object Oriented Design Practices. Basically, whoever has the information is responsible for handling it.
Blocks are used extensively in Apple's GCD (Grand Central Dispatch) to easily enable multi-threading. In general, you don't need to copy a block when you dispatch it on GCD. Oddly, this is slightly counter-intuitive (if you think about it) because if you dispatch a block asynchronously, often the method the block was created in will return before the block has executed, which generally would mean the block would expire since it is a stack object. I don't think that GCD copies the block to the stack (I read that somewhere but have been unable to find it again), instead I think the life of the thread is extended by being put on another thread.
Mike Ash has extensive articles on blocks, GCD and ARC which you may find useful:
Mike Ash: Practical Blocks
Mike Ash: Objective-C Blocks vs C++0x Lambdas: Fight!
Mike Ash: Q&A - More info on Blocks
Mike Ash: Automatic Reference Counting He talks about blocks & ARC in this article.
Mike Ash: GCD Is Not Blocks, Blocks Are Not GCD
Apple Docs - Introducing Block & GCD
This all looks good. Though, you might want to double-check the block parameter:
#property id myObject;
#property (copy) void (^myBlock)(NSString *);
....
- (void)testWithBlock: (void (^)(NSString *))block
{
NSString *testString = #"Test";
if (block)
{
block(test);
myObject = Block_copy(block);
myBlock = block;
}
}
...
[object testWithBlock: ^(NSString *test)
{
NSLog(#"[%#]", test);
}];
Should be fine. And I believe that they are even trying to phase out Block_copy(), but they haven't yet.
As the blocks programming topics guide says under 'Copying Blocks':
Typically, you shouldn’t need to copy (or retain) a block. You only need to make a copy when you expect the block to be used after destruction of the scope within which it was declared.
In the case you are describing, you can basically think about the block as simply being a parameter to your method, just like as if it were an int or other primitive type. When the method gets called, space on the stack will be allocated for the method parameters and so the block will live on the stack during the entire execution of your method (just like all the other parameters). When the stack frame gets popped off the top of the stack at the return of the method, the stack memory allocated to the block will be deallocated. Thus, during the execution of your method, the block is guaranteed to be alive, so there's no memory management to deal with here (in both ARC and non-ARC cases). In other words, your code is fine. You can simply call the block inside the method.
As the quoted text suggests, the only time you need to explicitly copy a block is when you want it to be accessible from outside of the scope where it was created (in your case, beyond the lifetime of the stack frame of your method). As an example, suppose you want a method that fetches some data from the web, and runs a block of code when the fetch is complete. Your method signature might look like:
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(void))completionHandler;
Since the data fetch happens asynchronously, you would want to keep the block around (likely in a property of your class) and then run the block once the data has been fully fetched. In this case, your implementation might look like:
#interface MyClass
#property (nonatomic, copy) void(^dataCompletion)(NSData *);
#end
#implementation MyClass
#synthesize dataCompletion = _dataCompletion;
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(NSData *fetchedData))completionHandler {
self.dataCompletion = completionHandler;
[self fetchDataFromURL:url];
}
- (void)fetchDataFromURL:(NSURL *)url {
// Data fetch starts here
}
- (void)finishedFetchingData:(NSData *)fetchedData {
// Called when the data is done being fetched
self.dataCompletion(fetchedData)
self.dataCompletion = nil;
}
In this example, using a property with a copy semantic will perform a Block_copy() on the block and copy it to the heap. This happens in the line self.dataCompletion = completionHandler. Thus, the block gets moved from the stack frame of the -getDataFromURL:completionHandler: method to the heap which allows it to be called later in the finishedFetchingData: method. In the latter method, the line self.dataCompletion = nil nullifies the property and sends a Block_release() to the stored block, thus deallocating it.
Using a property in this way is nice since it will essentially handle all of the block memory management for you (just make sure it's a copy (or strong) property and not simply a retain) and will work in both non-ARC and ARC cases. If instead you wanted to use a raw instance variable to store your block and were working in a non-ARC environment, you would have to call Block_copy(), Block_retain(), and Block_release() yourself in all the proper places if you wanted to keep the block around any longer than the lifetime of the method in which it's passed as a parameter. The same code above written using an ivar instead of a property would look like this:
#interface MyClass {
void(^dataCompletion)(NSData *);
}
#end
#implementation MyClass
- (void)getDataFromURL:(NSURL *)url completionHandler:(void(^)(NSData *fetchedData))completionHandler {
dataCompletion = Block_copy(completionHandler);
[self fetchDataFromURL:url];
}
- (void)fetchDataFromURL:(NSURL *)url {
// Data fetch starts here
}
- (void)finishedFetchingData:(NSData *)fetchedData {
// Called when the data is done being fetched
dataCompletion(fetchedData)
Block_release(dataCompletion);
dataCompletion = nil;
}
You know there are two kinds of blocks:
blocks stored in the stack, the ones that you explicitly write as ^{...}, and that disappear as soon as the function they are created in returns, just as regular stack variables. When you call a stack block after the function it belonged to has returned, bad things happens.
blocks in the heap, the ones that you get when you copy another block, the ones that live as long as some other object keeps a reference to them, just like regular objects.
The only reason for you to copy a block is when you are given a block that is, or may be a stack block (explicit local block ^{...}, or method argument whose origin you don't know), AND that you want to extend its life span out of the limited one of the stack blocks, AND that the compiler doesn't already do that job for you.
Think: keeping a block in an instance variable.
Adding a block in a collection such as NSArray.
Those are common examples of cases where you should copy a block when you're not sure it is already a heap block.
Note that the compiler does it for you when a block is called in another block.

Objective-C Memory Management: When do I [release]?

I am still new to this Memory Management stuff (Garbage Collector took care of everything in Java), but as far as I understand if you allocate memory for an object then you have to release that memory back to the computer as soon as you are finished with your object.
myObject = [Object alloc];
and
[myObject release];
Right now I just have 3 parts in my Objective-C .m file: #Interface, #Implementation and main. I released my object at the end of the program next to these guys:
[pool drain];
return 0;
But what if this program were to be a lot more complicated, would it be okay to release myObject at the end of the program?
I guess a better question would be when do I release an object's allocated memory? How do I know where to place [myObject release];?
This is probably a little over-simplified, but in general, you are going to want to release it where you declared it.
If you declare an object INSIDE a particular method call, then by definition, you will be done with that object (or at least that handle to that object) at the end of that method call... release it then.
If you declare an object as an instance variable, then by definition you will be done with it when that instance is destroyed... release it in the dealloc method of that class.
Keep in mind that "release" does not equal "destroy." When passing objects around in your application, it may make sense to have more than one handle to that object stored in different places... in that case "release" means "I'm done with this object, but someone else may still be using it." Deallocation only occurs when the number of "handles" (retain count) reaches zero.
Apple has some fantastic documentation on memory management, I would check it out at developer.apple.com.
You essentially have three kinds of objects, each with a different pattern.
Transients Objects
In general, you should autorelease transient objects. These are objects that are allocated locally and do not need to exist beyond the method in which they are called. Or they are passed around from method to method.
Chain of Ownership
When one object exists as an instance field inside another, you should release the "owned" (or "child") object when the "owner" (or "parent") object goes out of existence. This is done in the dealloc method of the parent object:
- (void) dealloc {
[child release]; // child was declared as an instance variable
[super dealloc];
}
Lifetime of the Program
When an object is intended to exist for the lifetime of the program, it usually isn't necessary to call release at all, unless some kind of resource cleanup needs to occur. You can put this in applicationWillTerminate:, which you can look up in Apple's documentation.
(You should probably avoid having such objects, but that is a discussion for another question.)
You have to think in terms of ownership. When you take ownership of an object by calling alloc, new or retain, you're also responsible for releasing it, either by calling autorelease when you return an owned object to the caller, or by calling release.
A general rule is:
Local variable: release it within the same method. When you want to return it to the caller, use autorelease
Class member: release it in the dealloc method

iPhone Simplest Communication between Threads

I have an iPhone app with a secondary thread to handle XML parsing. Inside some of those methods, I need to reference dictionaries (for look up, not modification) created and populated in the main thread.
Apple's documentation indicated to me that global variables might be the best way to accomplish this. I'm just now sure what the implementation would look like. Define the dictionaries at the top of .m and access them normally inside the secondary thread?
NSDictionary is thread-safe, so it's probably not a threading issue unless your initializer allocates the global as an NSMutableDictionary (not thread-safe) and then the secondary thread tries to access it while it's still being populated.
(If this is the case, your initializer should first allocate the NSMutableDictionary into a local variable, populate it, then copy the finished local to the global using NSDictionary's +dictionaryWithDictionary: or -initWithDictionary:.)
Alternatively, could it be that you're not retaining the global when initializing it?