Raw data types Vs Objects in Objective C - iphone

Something I've been wondering for a while. I know that in order to free up memory, objects (Such as NSMutableArray) have to be released, but raw data types (Such as int) don't. My question is, at what point does the space in memory that an int is occupying become free?
For example, a class "myClass" has an iVar "int a"
"a" holds the value some integer value.
When "myClass" is deallocated, does the space in memory that was holding the value for "a" become free straight away?
Thanks in advance.

For class ivars, the memory is freed when the object instance is deallocated - upon the last [release] call. For local int (and other primitive) variables, when the function returns. For global and static variables, when the process quits.
Also, you can allocate int's dynamically with malloc(). Then it's freed when you call free().

"a" is included in the memory allocated in "myClass". In other words, when myClass is deallocated, "a" is gone right along with it.

An Objective C object is similar to a pointer to a malloc'd C structure (containing both declared and a few hidden instance variables). When an object is released, the entire C structure memory block, including all internal ivar storage, is free'd (as well as any other dealloc housekeeping required).

Related

ARC doesn't apply to struct and enum, how are they deallocated in Swift

Since ARC doesn't apply to struct and enum, then how are they deallocated from the memory? I have to get stuck when it asked in the interviews and try to find the correct answer but can't find much info on it googling. I know swift is smart at handling value types. But how?
The memory management of objects (instances of classes) is relatively difficult, because objects can outlive a function call, the life of other objects, or even the life of the threads that allocated them. They're independent entities on the heap, that need book keeping to make sure they're freed once they're not needed (once they're no longer referenced from any other threads/objects, they're unreachable, thus can't possible be needed, so are safe to delete).
On the other hand, structs and enums just have their instances stored inline:
If they're declared as a global variable, they're stored in the program text.
If they're declared as a local variable, they're allocated on the stack (or in registers, but never mind that).
If they're allocated as a property of another object, they're just
stored directly inline within that object.
They're only ever deleted
by virtue of their containing context being deallocated, such as when
a function returns, or when an object is deallocated.

If a function returns an UnsafeMutablePointer is it our responsibility to destroy and dealloc?

For example if I were to write this code:
var t = time_t()
time(&t)
let x = localtime(&t) // returns UnsafeMutablePointer<tm>
println("\(x.memory.tm_hour): \(x.memory.tm_min): \(x.memory.tm_sec)")
...would it also be necessary to also do the following?
x.destroy()
x.dealloc(1)
Or did we not allocate the memory and so therefore don't need to dismiss it?
Update #1:
If we imagine a function that returns an UnsafeMutablePointer:
func point() -> UnsafeMutablePointer<String> {
let a = UnsafeMutablePointer<String>.alloc(1)
a.initialize("Hello, world!")
return a
}
Calling this function would result in a pointer to an object that will never be destroyed unless we do the dirty work ourselves.
The question I'm asking here: Is a pointer received from a localtime() call any different?
The simulator and the playground both enable us to send one dealloc(1) call to the returned pointer, but should we be doing this or is the deallocation going to happen for a returned pointer by some other method at a later point?
At the moment I'm erring towards the assumption that we do need to destroy and dealloc.
Update #1.1:
The last assumption was wrong. I don't need to release, because I didn't create object.
Update #2:
I received some answers to the same query on the Apple dev forums.
In general, the answer to your question is yes. If you receive a pointer to memory which you would be responsible for freeing in C, then you are still responsible for freeing it when calling from swift ... [But] in this particular case you need do nothing. (JQ)
the routine itself maintains static memory for the result and you do not need to free them. (it would probably be a "bad thing" if you did) ... In general, you cannot know if you need to free up something pointed to by an UnsafePointer.... it depends on where that pointer obtains its value. (ST)
UnsafePointer's dealloc() is not compatible with free(). Pair alloc() with dealloc() and malloc and co. with free(). As pointed out previously, the function you're calling should tell you whether it's your response to free the result ... destroy() is only necessary if you have non-trivial content* in the memory referred to by the pointer, such as a strong reference or a Swift struct or enum. In general, if it came from C, you probably don't need to destroy() it. (In fact, you probably shouldn't destroy() it, because it wasn't initialized by Swift.) ... * "non-trivial content" is not an official Swift term. I'm using it by analogy with the C++ notion of "trivially copyable" (though not necessarily "trivial"). (STE)
Final Update:
I've now written a blogpost outlining my findings and assumptions with regard to the release of unsafe pointers taking onboard info from StackOverflow, Apple Dev Forums, Twitter and Apple's old documentation on allocating memory and releasing it, pre-ARC. See here.
From Swift library UnsafeMutablePointer<T>
A pointer to an object of type T. This type provides no automated
memory management, and therefore the user must take care to allocate
and free memory appropriately.
The pointer can be in one of the following states:
memory is not allocated (for example, pointer is null, or memory has
been deallocated previously);
memory is allocated, but value has not been initialized;
memory is allocated and value is initialized.
struct UnsafeMutablePointer<T> : RandomAccessIndexType, Hashable, NilLiteralConvertible { /**/}

Memory management about CGPoint

refer to CGPointMake explaination needed?
Correct me if I am wrong, in the implementation of CGPointMake, CGPoint p; declare a local variable of a struct, which should should be freed after leaving the scope. But why the function can return the value without risk?
Anyway, assume that implementation of CGPointMake is correct, should I free the CGPoint that created by CGPointMake?
It doesn't need to be freed, because it never lived on the heap. Only heap-allocated memory needs to be freed. Memory that is allocated on the stack (as is done in CGPointMake()) will be cleaned up automatically after the method/function exists.
The function can return a point because the compiler sees "Aha, this function wants to return a struct, which is sizeof(CGPoint) bytes big, so I'll make sure that there's enough space in the return value memory slot for something that big." Then as the function exits, the return value is copied in to the return memory slot, the function exits, and the value in the return slot is copied over to its new destination.
The function can return a CGPoint because the struct is "small enough" to be returned directly from a function. You're not returning a pointer, you're returning the whole thing directly. Same with methods that take CGPoints as parameters-- you can pass the whole thing by value directly.
As Dave notes, CGPoints aren't objects, they're just structs. CGPointMake doesn't "allocate" memory. It's just a function that returns a struct set up with the right sizes, which you then usually capture into a local on your own stack or pass along or whatever.
Like any other primitive type (int, float, or other struct), it doesn't need to be freed when it goes out of scope.
(Note: many architectures/compilers/"application binary interface"s have optimizations and size limits regarding the size of a thing used as an argument or return value. In this case, a CGPoint could actually fit entirely inside one 64-bit register (2x 32-bit floats) which makes it no more heavyweight than returning an int. But the compiler can also do other tricks as far as copying in and out larger structures e.g. CGRect.)

iOS Memory Management: ivars, static, and NSStrings

I have managed to get myself confused about some elements of memory management. I am new to objective-c, and memory managed languages generally.
I have read the memory management guidelines, but I remain confused about a couple of things.
1) Is there any need to clean up ivars, and method variables that are not retained by any object. For instance
-(void) someMethod{
int count = 100;
for (int i=0; i <count; i++) {
NSLog(#"Count = %d", i);
}
}
What happens to the "count" var after the method is complete?
If a method allocates lots of temporary variables, do those get removed from memory as long as they are not unreleased, alloc'd objects? Or do i need to set them to nil in some way?
2) If i have a static variable, for instance an NSString, do I have to do anything for that to be removed from memory when the class is dealloced?
3) I have noticed that NSStrings seem to have a retainCount of 2147483647 which wikipedia tells me is the max value for a 32 bit signed integer.
http://en.wikipedia.org/wiki/2147483647
myString retainCount = 2147483647
-(void) someMethod{
NSString *myString = #"testString";
NSLog(#"myString retainCount = %d", [myString retainCount]);
// logs: myString retainCount = 2147483647
}
What happens to this at the end of the method? Does this memory ever get emptied? The string is not being referenced by anything. My understanding is that the #"" convenience method for NSString returns an autoreleased object, but whats the point of autoreleasing something with a retainCount of 2147483647 anyway? In that case, whats the point of retaining or releasing ANY NSString?
I am well aware that retainCount should be ignored, but it just bugs me not to know what's going on here.
4) Does this matter at all? I know that the memory associated with an NSString isn't much to write home about, but I want to be a good memory management citizen, and I'm more interested in best practices than anything else.
Retain/release only matters for objects, not int, bool, float, double or other built-ins. So use it for id or other classes that you hold a pointer to an object. In your example, count doesn't need to be retained or released. It is allocated on the stack which is automatically cleaned up when the function returns.
You do need to deal with any local objects you alloc. Those are created with a retainCount set to 1, so you need to either hold on to them for later or release them. Most Cocoa functions (that don't start with copy or alloc) return an object that is autoreleased. This means that they will have release called on them later -- you can only hold these after the function if you call retain on them. If you want them to be cleaned up, you don't need to do anything (calling release would result in too many release calls).
If you have a static variable pointing to an object, then it is not touched when objects of that class are dealloced. If you want it to be released, you have to call release on it. If the static is an int, bool, or other built-in, you don't (can't) call release on it. That's part of the global memory of your app.
NSStrings that are set to string literals should not have release called on them. The retainCount is meaningless for them. That value is also -1 for signed int values.
If you do this -- [[NSString alloc] initCallHere:etc] -- you have to call release on it. Most of the time you get strings, you don't use alloc, so you don't need to call release. If you retain one, you need to call release.
Yes, it does matter. Over time leaks will cause the iPhone to kill your app.
You don't need to worry about count cause it's an integer, a primitive data type, not an object.
I've read that those just go away upon app termination or if you explicitly release them.
You are right in that you should not worry about the retain count in that way. Cocoa automatically gives #"" (NSConstantString objects) the absolute highest retain value so that they cannot be de-allocated.
You are over complicating the subject. The point of the three guidelines is so that you know that you only have to worry about memory management in three specific situations. Apple gives you these guidelines so that one doesn't have to worry about the specific internals for every single class (like manually tracking retainCount), not to mention that sometimes Cocoa does things differently (as with NSConstantString). As long as you remember these guidelines, you really don't have to know the very gritty details of what's going on underneath (of course, an understanding of the retain count concept helps, but compare this to manually tracking it).
I don't know which guide you read specifically, but if you haven't given this one a try, I highly recommend it. It summarizes the three guidelines in a concise and direct manner.
The Cocoa memory management rules only cover Objective C objects.
Local variables (non-static) are cleaned up when any subroutine or method exits (actually the stack memory is just reused/overwritten by subsequent subroutines or methods in the same thread). Constants which require memory (strings) and static variables are cleaned up when the app is torn down by the OS after it exits. Manually malloc'd memory is cleaned up when you manually free it.
But any object you alloc or retain: (whether assigned to an ivar, local, global, static, etc.) has to managed like any other object. Be careful assigning objects to global variables, unless you are really good at retain count management.

Correct Memory Management for [string UTF8String]

I'm somewhat new to objective-c and I'm not sure what the correct memory management for this code is.
const unsigned char * data =(const unsigned char *) [string UTF8String];
When I call free on data I get an error. Do I need to clean up after this call?
No. "UTF8String" does not contain the words alloc, copy, retain, or create. Thus, you're not responsible for that memory.
Note that if you want that data to stick around after string is released, you should copy it; by the contract, you're not responsible for that memory, but you are also not guaranteed that it will last beyond the scope of the object that gave it to you.
You do not need to free it.
In Cocoa, if a method does not contain the words alloc, init, or copy, you do not own the object that is returned from said method.
-UTF8String actually points to the cstring representation of the NSString object you are calling it on. When the object's state changes, the UTF8String also changes.
As stated in the documentation, it is automatically freed the same way an autoreleased object would be.
technically speaking, free() is used to remove memory allocated using malloc() from the heap.
malloc() was not used to allocate the memory. remember that objective-c is c with extensions.
the data variable will remain in memory based on the c language 'scoping' rules.