How to check if an object is alloced or not? - objective-c

Is there anyway to check if an object is alloced or not? Thanks.
Edit: Here's a better question. Is it ok to alloc an object that was already alloced without changing it's initial value?

You may intend how to check if a pointer points to an allocated object (which, as long as it stays in memory, is referenced by an unique memory address). In that case you could test if that pointer is nil in an if statement (or simply call is name in the condition, since objective-C inherits from C the evaluation of truth conditions, ie if it is not zero than it is true)

No. You can check whether an object is initialised assuming you control the object, by having it change its state once it's fully initialised. However an alloced object is just a block of memory with a pointer at the start. The only possible test would yield too many false positives.
Another way to look at it is this: there is no such thing as an object that has not been alloced.

Related

Does copy also transfer the retain count?

Suppose I have an object, for example an NSString, with retain count 5. When I call copy on it, I get a new copy of the object; does this new object have the retain count of its original object ?
It depends. copy is a convenience method for copyWithZone:,
and the "NSCopying Protocol Reference" states:
Your options for implementing this protocol are as follows:
Implement NSCopying using alloc and init... in classes that don’t
inherit copyWithZone:.
Implement NSCopying by invoking the
superclass’s copyWithZone: when NSCopying behavior is inherited. If
the superclass implementation might use the NSCopyObject function,
make explicit assignments to pointer instance variables for retained
objects.
Implement NSCopying by retaining the original instead of
creating a new copy when the class and its contents are immutable.
(I have modified the following two statements after all that feedback.)
For example, NSString is an immutable object, and copy just retains the object
and returns a pointer to the same object. Retaining the object might increase the
retain count, but not necessarily (as in the case of string literals.)
Copying an NSMutableString would probably create a new object and return that.
The new object would have its own retain count independent of the original object.
But you should not care about the difference. With manual reference counting,
copy returns an object that you own and have to release eventually.
With ARC, the compiler with automatically handle that.
copy returns an object that is a semantic [shallow] copy(1) of the object. What the copy method returns is an implementation detail; it may return the same object, it may return a different instance of the same class, or it might even return an instance of a different class.
Doesn't matter.
What matters is that the returned object, under manual retain/release, has a retain count of +1. Not 1, but +1. It might actually be 1, 42, 981, or -1. Doesn't matter.
All that matters is that you must balance that retain with a release or autorelease somewhere if you want to relinquish the object back to the system. Which may not actually cause it to be deallocated; that is an implementation detail of no concern (until optimization time, anyway).
(1) semantic [shallow] copy means that the object returned is an effective shallow copy. The state contained within the copied object (but not within objects contained within the object -- that is the shallow part) will not change when the original object changes state. For a mutable object, copy must actually create a new instance of some object -- most likely an immutable variant class -- that can contain the original state.
For an immutable object, the copy method might be simply implemented as return [self retain];. Or, in the case of static NSStrings (NSCFStrings), it might simply be return self; as retain/release/autorelease are no-ops on such strings.
No, a copied object will have a retain count of 1, just like a newly initialized object.
I highly recommend you read the Memory Management Guide if you wish to learn more.
If you're new to iOS development, the iOS App Programming Guide should be read first, and is a great use of your time.
I just noticed you didn't tag this as iOS specific, if you're coding for Mac, the Programming with Objective-C guide might be more appropriate for you.
To really get your head around this issue, don't think in terms of retain count, think in terms of pointer ownership (like ARC does).
If an object has a "retain count" of 5, that means five pieces of code somewhere are each holding a (strong) pointer to its memory address. If you copy that object, you get a pointer to the address of the new, copied object. The other five pieces of code are still pointing to the original object. There's only one piece of code pointing to the new object, so its "retain count" is one.
As noted in other answers, the Memory Management Guide definitely helps make this all clear.
Why did I put "retain count" in quotes? Because it's only useful as a general concept -- you shouldn't be using retainCount directly, or you'll hear from #bbum.
Objective-C plays some clever tricks when you ask it to copy objects, and as a result retain counts might not be what you think they should be.
Let's say you have an object pointer x with a retain count of n, and call the copy method which returns an object pointer y.
NSObject* x = ...;
NSObject* y = [x copy];
Then the rule is that if you release x n times, and release y once, all objects will be gone. Usually this is achieved by leaving x unchanged, and giving y a retain count of 1.
However, if x points to an immutable object, then Objective-C may decide that no copy needs to be done. The result is that y = x. Still, the rule above still applies: Releasing x n times and y once (even though they are the same object) will free all the objects involved. That's achieved by the copy method returning x with a +1 retain count.
Copy on mutable object like NSMutableArray will create a new copy and retain count will be 1 while copy immutable object like NSArray will point to same reference and increase the retain count by 1.

Are there any issues with continually replacing an object in an array?

I've got some code where I need to replace one object in an array with another. The code as it stands won't check if that object has already been replaced but instead will just keep replacing it, can this cause problems? and if so should I check to see if the array already contains the object and not replace if it does? The line I'm using is..
[subArray replaceObjectAtIndex:col withObject:obj];
I'm using ARC is that makes a difference.
The replaceObjectAtIndex: method retains the new object, releases the old object, and makes an assignment into the array that backs the NSMutableArray's data. These operations will not cause memory issues even when the object being assigned is already stored in the array at the same position. These operations are performed very quickly, so checking equality before the assignment would likely be a waste of time.

Objective C: Returning Objects from Methods

I'm learning how to program, and starting off with Objective C. I'm trying to understand exactly what happens when an object is allocated from within a method.
-(Fraction *) add: (Fraction *) f
{ //'result' will store the result of the addition
Fraction *result = [[Fraction alloc]init];
result.numerator = (numerator*f.denominator + denominator*f.numerator);
result.denominator = denominator*f.denominator;
[result reduce];
return result;
}
I understand that I can create an object to store 'result' in when it is returned,
tempStorageObject = [aFraction add: bFraction];
and that i am then responsible for releasing it, but what happens when I don't store it, as in:
[aFraction add: bFraction];
NSLog(#"%i/%i", result.numerator, result.denominator); //result object not declared in main
I am told that I have an undeclared identifier. I get that, but what exactly happens to 'result' after using my 'add' method. Where does it go? Shouldn't I be able to access its variables since it was created and returned in the method? Obviously not, but I'm not clear on why. I've tried re-reading my book and searching this forum but I can't find a clear answer. Thanks. (First post)
Four different things:
Properties
Local variables
Function return values
Heap storage
"I get that, but what exactly happens to 'result' after using my 'add' method. Where does it go?"
It's a local variable. It's gone.
"Shouldn't I be able to access its variables"
Seeing your comment, it looks like you mean access by dot notation. No, dot notation is for properties.
"since it was created"
Dot notation does not give you access to local variables.
"and returned in the method?"
Dot notation does not give you access to function return values.
All of the first three things are pointers, when they refer to objects. The fourth thing is what they point to. When you do alloc, you create an object in heap storage. You then have instance variables, properties, local variables, and function return values refer to the heap storage. In a way you think of them as being the same thing as the object in heap storage. Syntactic sugar like dot notation helps you do that. Your object will last, but in this case the different variables that refer to it are limited in scope and come and go.
When you call alloc, an object is created on the heap.
When you assign it to result, result now has the same object.
When you return result, the local variable result no longer exists, the return value temporarily holds the same object, and the object still exists in the heap.
4a. When you assign the function result to tempStorageObject, another local variable (I guess), the function result goes away. It existed only temporarily to pass a value from inside the function to out. tempStorageObject now holds the object, and the object still exists in the heap.
4b. Instead if you don't assign the function result to anything, then the function result still goes away. But the object still exists on the heap. You have a problem. You have an object on the heap, but you can't refer to it directly there (unless you are good at guessing its address). Without being able to refer to it, you can't get it off the heap, which will be a major problem if you do that kind of thing over and over. The heap will start to get full with objects you can't get rid of and you'll run out of memory. That's what's called a leak.
The correct thing to do in this case is to return [result autorelease]. When you call [something autorelease], it adds "something" to an "autorelease pool" and then returns the same something.
You call alloc and create an object on the heap. Its retain count starts at 1.
You assign it to result, a local variable. Result has the object and it's on the heap.
[result autorelease]. result has the object, it's in an autorelease pool, and it's on the heap.
return that. result is gone, the return value has the object, it's in the autorelease pool, and it's on the heap.
5a. Assign the return value to tempStorageObject. The return value is gone, tempStorageObject has the object, it's in an autorelease pool, and it's on the heap.
6a. You leave the scope of tempStorageObject. tempStorage object is gone. The object is in an autorelease pool and on the heap.
5b. You don't assign the function result to anything. The function result is gone. The object is in an autorelease pool and on the heap.
7ab. The autorelease pool is drained. That is usually done from code in the main run loop provided by the system library, but you can do it yourself if you know how. All the objects in the autorelease pool, including the one we're paying attention to, are sent a release message. The object's retain count goes to 0.
8ab. With a retain count of 0, the object is removed from the heap. The object is in the autorelease pool.
9ab. The second thing drain does is remove all the objects from the pool. Now the object doesn't exist anywhere anymore.
You said you are familiar with release, so I just say you should use autorelease keyword, which releases the allocated object when no more code blocks need it, check document below, from Apple:
Memory Management Programming
The scope of alloc is global: once you have allocated an object, there is room for it in memory and that memory will remain allocated until the release count hits zero (or the app is terminated). Until then, the object will still exist.
The scope of a variable is much shorter. In your example 'result' goes out of scope right at the end of the method 'add'. But that variable is just a name, a reference to an object. So whoever is calling add, should make sure to do something with the returned object. Otherwise there is no more variable referring to the object and so it can not be released.

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

What is the difference between "copy" and "retain"?

What is the difference between copy and retain for NSString?
- (void)setString:(NSString*)newString
{
string = [newString copy];
}
In a general setting, retaining an object will increase its retain count by one. This will help keep the object in memory and prevent it from being blown away. What this means is that if you only hold a retained version of it, you share that copy with whomever passed it to you.
Copying an object, however you do it, should create another object with duplicate values. Think of this as a clone. You do NOT share the clone with whomever passed it to you.
When dealing with NSStrings in particular, you may not be able to assume that whoever is giving you an NSString is truly giving you an NSString. Someone could be handing you a subclass (NSMutableString, in this case) which means that they could potentially modify the values under the covers. If your application depends on the value passed in, and someone changes it on you, you can run into trouble.
Retaining and copying are two different things, the first
is conceptually call-by-reference while the second is call-by-value.
retain : It is done on the created object, and it just increase the reference count.
copy -- It creates a new object and when new object is created retain count will be 1.
Hope This Help for U...:)
Its an old post but here's my view on the question
Retain increases the retain count of an object by 1 and takes ownership of an object.
Whereas copy will copy the data present in the memory location and will assign it to the variable so in the case of copy you are first copying the data from a location assign it to the variable which increases the retain count.
Just remember that retain works on reference and copy works on value
if you use retain, it copy the pointer value from original one.retain also increment the reference count by one.
but in case of copy, it duplicate the data referenced by the pointer and assign it to copy's instance variable.
The biggest difference is that if you use copy, the object you are copying must implement the NSCopying protocol (very easy to do). Not every object implements that, so you need to use care you know for sure what type you'll be operating against (or check for support of that protocol) when trying to call copy.
The best rule of thumb to using copy I can think of, is to always set NSString properties to "copy" instead of retain. That way you get more accurate readings from the Leaks instrument if you mess up and forget to release a string an object is holding onto. Other uses of copy need to be more carefully thought out.
Retaining an object means the retain count increases by one. This means the instance of the object will be kept in memory until it’s retain count drops to zero. The property will store a reference to this instance and will share the same instance with anyone else who retained it too. Copy means the object will be cloned with duplicate values. It is not shared with any one else.
copy: creates a new instance that's a copy of the receiver. It means that you'll have 2 different
retain: Increases the retainCount of the receiver. An object is removed from memory - (with dealloc), when retainCount is 0.
retain attribute is specified such that it can retain the another memory i.e it can be made to point to another address also
copy First copies the address and then retains it.