Does objective c compiler automatically set retain in property setting methods? - objective-c

In Objective C, if I have a class, within the class a method that creates a string using some convenience method and set the property NSString pointer to the newly created string. In this case, because the string is created using convenience method, it will have one owner which is the autorelease pool. When I assign the string to the property NSString pointer, will the compiler set the property as an owner to that string by inserting a retain call?
I think it should. Otherwise, when the autorelease pool is drained, the string will be released. However, if the object of the class still lives outside the autorelease pool, the property will point to memory that is already released, which causes a premature deallocation issue. In this case, there should be a retain call to set the object as a new owner to the string. Am I right on this?

The phrase "assign the string to the property NSString pointer" is a bit ambiguous. If you use the property setter either as a method invocation or with dot syntax the memory management specified or defaulted for the property will be used. If you assign directly to the underlying pointer, then you are bypassing the property attributes and the retain state will remain whatever it was before assignment.

Related

use of [release] in objective C

I have a doubt regarding memory management in Objective-C.
-(void)viewDidLoad
{
NSNumber *num=[[NSNumber alloc] initWithInt:10];
[num release];
NSLog(#”%i”,num);
}
The above code is working fine by printing the value. But as soon as the object has been released it loses its value right? Then how come its working fine?
Here's what's going on. First you do this:
NSNumber *num=[[NSNumber alloc] initWithInt:10];
Your num variable now contains a pointer to an NSNumber object, and (because you used alloc) you own that object. Then you do this:
[num release];
When you sent release to the object, you relinquished your ownership of it. The object might still exist and be unchanged, or it might have been destroyed. You don't know. Your num variable still contains the same pointer, but the memory it points to might not be a valid object now so you cannot safely send messages to that object.
Then you do this:
NSLog(#”%i”,num);
In this NSLog statement, you are treating num as an integer, not as a pointer, because %i formats an integer. You're just printing the address (memory location) where the NSNumber object was (and might still be - you don't know). So it doesn't matter whether num points to a valid object or not; you're just treating num as an arbitrary int. You're not trying to send any messages to the NSNumber object.
By Calling [release] on object we can decrement retain count of the object.
If object is created by calling method which is having copy, new, alloc in it the caller is said to be owner of that object and owner
should alway release owned object.
If you are not owning the object you should not release it.
Always call release on object when object is retained which means if one call retain method the corresponding release call should be
invoked .Retain release should be matched.

Under ARC, are Blocks automatically copied when assigned to an ivar directly?

Assume the following code under ARC,
typedef void (^MyResponseHandler) (NSError *error);
#interface MyClass : NSObject
{
MyResponseHandler _ivarResponseHandler;
}
- (void)myMethod:(MyResponseHandler)responseHandler
{
_ivarResponseHandler = responseHandler;
...
}
Question: Is the block automatically copied to the heap when assigned to the ivar?
My previous question implied that it is copied when assigned through a #property. But, today I used the above code and received an EXC_BAD_ACCESS that was fixed by changing to
_ivarResponseHandler = [responseHandler copy].
Edit: My previous answer was likely wrong.
Some selected excerpts from the ARC docs say:
3. Retainable object pointers
A retainable object pointer (or retainable pointer) is a value of a retainable object pointer type (retainable type). There are three kinds of retainable object pointer types:
block pointers (formed by applying the caret (^) declarator sigil to a function type)
4.2. Semantics
Assignment occurs when evaluating an assignment operator. The semantics vary based on the qualification:
For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores.
4.4.1. Objects
If an object is declared with retainable object owner type, but without an explicit ownership qualifier, its type is implicitly adjusted to have __strong qualification.
7.5. Blocks
With the exception of retains done as part of initializing a __strong parameter variable or reading a __weak variable, whenever these semantics call for retaining a value of block-pointer type, it has the effect of a Block_copy. The optimizer may remove such copies when it sees that the result is used only as an argument to a call.
So I think the answer is maybe, depending on the optimizer.
Your problem and solution indicate that my answer to your other question was probably wrong. I based it on the last paragraph of section 7.5 of the clang Objective-C Automatic Reference Counting documentation:
With the exception of retains done as part of initializing a __strong parameter variable or reading a __weak variable, whenever these semantics call for retaining a value of block-pointer type, it has the effect of a Block_copy. The optimizer may remove such copies when it sees that the result is used only as an argument to a call.
I took “these semantics” to mean the whole document, but if “these semantics” to refers to only section 7.5, then ARC only inserts a Block_copy for a block that is captured by a block.

How to resolve 'Potential Leak' issue

I am using the 'analyze' tool in xcode to check for potential leakages in my app.
I am getting the following warning as a result.
How do I resolve the potential leak shown above? "self.answerArray" is just an array I declared in my header file
You've called mutableCopy on the array (which returns a new array with a retain count of +1 - You own it), and you assign it to a property (which I assume is a strong/retain property) and you're not releasing it. You're leaking the memory.
You should release tempArray after assigning it to the property - and ensure the property is released in your class' dealloc method.
You should either send retain/release to answerArray (release old object before assigning a new one, retain the new object), or, probably better, declare a property
#property (retain) NSArray* answerArray;
this way compiler will generate release/retain (on assign) for you. See documentation. Otherwise the object answerArray was referencing before the assignment (answerArray = tempArray) will remain dangling in memory.
In case you will use a declared property, make sure to add your temp variable to autorelease pool:
tempArray = [[self.answerArray mutableCopy]autorelease];
or just send it release yourself (right before it goes out of scope).

Objective-c dealloc of boolean value

How would I dealloc a boolean value?
Deallocing it this way below gives me a warning: Incompatible pointer to integer conversion assigning to 'BOOL' (aka 'signed char') from 'void *'
- (void)dealloc {
self.booleanVar = nil;
[super dealloc];
}
Perhaps I should clarify, this is from a simple class inherited from NSObject.
I'm using the self.var = nil pattern that you see in Cocoa Touch classes. Let's say if it was an NSString* instead should I use self.var = nil or [var release] in the deallocmethod? I'm a little confused here.
You don't need to do it. It is not an object. This also explains the warning, as you're trying to assign a nil pointer (that's a NULL for objects basically) to a non-object.
Regarding your second question, yes. You can think of primitive variables as being part of the object, so when it's deallocated the vars will not exist anymore.
But when you have a NSString * in an object, it's just a pointer to another object. If you dealloc the former, the pointer will be deleted, not the NSString. No one might point to it, it's kind of lost in the air, occupying memory. So, before deleting the pointer, if you won't need the object anymore, you send it a release message. That's done in the dealloc method, since it's called to "delete" and object and thus is a good place to delete also every other object that has no use anymore.
You dont need to dealloc a BOOL, since BOOLs are really just a byte, which is a primitive data type. You only need to dealloc objects which have been allocated to memory.
First of all, if booleanVar is just a plain BOOL value, as in it is declared like so:
BOOL booleanVar;
then you do not need to free up any memory associated with it, since that memory is allocated and freed when the class that holds it is allocated and deallocated. So no code for booleanVar in dealloc will be fine.
However, if you are talking about a pointer for a BOOL, defined like so:
BOOL *booleanVar;
and what you want is to set this variable to a non-value, you should set it equal to NULL instead of nil, since NULL is for value pointers and nil is for object pointers (see: NULL vs nil in Objective-C).
However, if what you want is to free up the memory that the BOOL pointer points to, allocated with malloc or realloc, etc, then try the free() C function (see: http://www.cplusplus.com/reference/clibrary/cstdlib/free/).
What would really clear all this up is if you showed us the property declaration for booleanVar in the class interface, which would tell us exactly what you want to do and you would get an answer with complete certitude.

Why retain a static variable?

Isn't it unnecessary to retain a static variable since it stays around for the duration of the program, no matter if you release it?
See this code:
https://github.com/magicalpanda/MagicalRecord/blob/master/Source/Categories/NSManagedObjectContext+MagicalRecord.m#L24-29
I'm assuming you mean a static object pointer, such as static NSString *foobar;.
Such variables indeed have a lifetime as long as the application, but the variables we're talking about are pointers only. In Objective-C, objects are always dynamically allocated, and so we always address them with a pointer to their type, but the underlying data for an object is still present out in the dynamically allocated wild blue yonder.
You must still retain the object because, while the pointer to the object will never go out of scope, the object itself can be deallocated just like any other object, and so your pointer will end up pointing to garbage, or worse, another unrelated object.
A simplified version of Jonathan Grynspan's accepted answer:
The retain isn't for the variable which points to an object. That variable will last forever because it's static. The retain is for the object the variable points to. Without the retain the object could (and should) be deallocated. Then you've got a variable pointing to a thing which will cause a sigabrt. This variable pointing nowhere is known as a "dangling pointer."
For the ARC context, the best thing to do is declare the static variable as strong, so something like this:
static ThatClass * __strong thatStaticVariable;
This ensures that the object that thatStaticVariable points to will be a valid object (i.e., never gets deallocated) once assigned. However, you don't actually need the __strong keyword at all, because it's the default (so sayeth the docs, thanks to #zpasternack), so just use
static ThatClass *thatStaticVariable;
and you're good.
Note: forever = while the application is running