Consider the following example:
- (void)exampleFunction
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
SomeClass *classObject = [[SomeClass alloc] init];
[classObject someFunctionThatDoesBackgroundWorkAndCallsACompletionBlock:^(NSDictionary *results) {
SomeNeatObject *object = appDelegate.someNeatObject;
[object doSomeNeatStuff:results];
}];
}
Making an assumption that the completion block is executed on the main/UI thread to avoid additional insanity, here's what I'm unsure of:
I realize that the appDelegate should not be overused, but it is useful for it to hold information about the current state of the application, such as Core Data-related objects if you use Apple's templates for initializing a Core Data stack (at least on iOS projects). That particular case (Core Data) has me concerned as much of that stack is not thread-safe nor is it a good idea to be copying it.
Thanks in advance.
Your example will not compile because delegate is not defined. I assume you mean "SomeNeatObject *object = appDelegate.someNeatObject;"
In this example, appDelegate is a variable, whose value will be captured by the block. It's no different than any other variable.
It's not unsafe, because [[UIApplication sharedApplication] delegate] always returns the same thing, unless you change the delegate, which you probably don't.
The fundamental concepts here are: appDelegate is a variable which points (or refers) to an object (or instance) of type AppDelegate. In an iOS app there is one such instance, which is returned by [[UIApplication sharedApplication] delegate]. If you create a reference to appDelegate inside a block, you are making a copy of the variable, not the object. So in your code's block:
SomeNeatObject *object = appDelegate.someNeatObject;
This is semantically the same as putting the following code in the block (casts omitted):
SomeNeatObject *object = [[UIApplication sharedApplication] delegate].someNeatObject;
The SomeNeatObjects being referred to are the same thing.
Slightly more advanced concept: any object has an address in memory (an integer, usually seen in hexadecimal). If two variables have the same hexadecimal value, they point to the same object. If they have different values, they point to different objects. In your example, appDelegate (outside block) and appDelegate (inside block) have the same value, therefore point to the same object.
If you were to do this:
AppDelegate * otherDelegate = [appDelegate copy];
Then you would be making a copy of the object pointed to by appDelegate. But don't do this, please.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With