Difference between an object and a pointer - objective-c

as the title says, what is the difference between a pointer and an object.
Say I have this code..
NSString *red = [[NSString alloc]initWithFormat:#"%#"];
and this code..
NSString *blue = [NSString stringWithFormat:#"%#"];
Is it correct to assume that they're both pointers to an object and pretty much the same? And if so, how should I think of objects in my mind ?
I do apologize if the answer exists already, I did use the search function but I've only found examples of this in the C++ language and wanted to make sure how it was in objective-c.

In addition to Basile Starynkevitch and Bram's answer,
In objective C the difference between your code line is,
NSString *red = [[NSString alloc]initWithFormat:#"%#"];
**Above code says you own red object so it's your responsibility to release it.
NSString *blue = [NSString stringWithFormat:#"%#"];
**You don't own it someone else in your program deep down inside will own this and you don't have to release this.
I would suggest for more information reading Apple's documentation is GREAT! specially Learning, "Objective C programming guide"
Good luck!
PS : iOS 5 has new feature, memory management is done by iOS itself, Now developer can be more creative instead doing 3 grade mathematics of reference counting :)

Pointers are a C concept, and they're identical in C, C++, and Objective-C. They are simply an integer that holds the memory address where an object is stored. In your example, both of those messages dynamically create an NSString object. Where that object is stored in your application's memory is up to the OS to decide, and you really don't care. So the OS allocates some memory and stores an instance of NSString in it. It then gives you back a pointer to that object, which you can use to reference the actual object at a later time.

A pointer contains the address in memory where is stored the object.
Memory address Object
-------------- ---------
0
1
2
3
4
...
pointer ----> 10523 myObject1
10524
...

An object is an instance of a class. It takes up memory while and should be released when you are finished with it. The pointer is your reference to the object.
NSString *red = [[NSString alloc]initWithString:#"red"];
and this code..
NSString *blue = [NSString stringWithString:#"blue"];
red and blue are both pointers to different objects.
The importance difference here is that red is owned by you and blue is not
[[NSString alloc]initWithString:#"red"];z
returns an object that you own and have to release later
[NSString stringWithString:#"blue"];
returns an object that is not owned by you and will be released the next time the autorelease pool is emptied
These concepts are covered in The Objective-C Programming Language guide by apple (I pointed you to the specific section, its a huge document, but the section 'Objects, Classes, and Messaging' should be the most helpful to your questions)

i hope i can make this abit clearer.
the object is in memory. the pointer is like an arow to the memory where the object is.
see it like a directional sign to a building.. the building is the object, the directions are the pointers.

(I'm not an Objective C expert, but)
Think of objects as memory zones, a pointer refer to the zone but is not that zone.
Gross analogy: your car plate number is not your car. A number is a number (made of digits, or more abstractly an element of the set of naturals). A car is something you drive.

Also not an Objective-C expert. Here's my best guess.
Both of those types seem to be pointers. However, it looks like the difference is that the first (where you are using alloc) puts you in charge of the associated memory.
With the second type, if you instantiate the object, use it, whatever, and then it goes out of scope, the OS will likely clean it up for you. However, with the first type, you are in charge of releasing that allocated memory back to the OS.
I'm guessing that objective-C has some sort of reference counting and memory management built in to detect when that object is no longer being referenced anywhere, but the important part is that that object should persist beyond the scope of that declaration as long as you've still got a reference somewhere.
You can probably find a lot of information by reading this post: Objective-C pointers?
As far as the general definition of "object" and "pointer": Both of those types are pointers. One you are in charge the memory, and the other the OS takes responsibility for you. An object is simply defined as an instance of a class. A pointer is the memory address of that instance.

Related

Casting a memory location is disabled in ARC... How to get contents of the object then?

I used to be able to do this in Objective-c.
Now ARC disables this:
NSString *mice = #"dogs eat cats";
long dog = (long)mice;
NSString *appled = (NSString *)dog;
Am I missing something. If I know the address of my object how can I get the contents of it?
And it uses less memory (in your own comment on your question)
It uses exactly the same amount of memory: storing an n-bit pointer as an n-bit integer takes n-bits!
You should carefully review why you are doing this and whether your code will remain safe under ARC.
Pre-ARC you could "hide" a reference to an object and that object would stay around until you issued an explicit release().
Post-ARC there are bridge casts (multiple kinds exist) which enable you to explicitly take responsibility for object lifetime, and to later transfer the responsibility back.
To "hide" the reference as you do in your example therefore requires two bridge casts, one in each direction. Failure to do this correctly will result in objects being automatically released by ARC and memory faults/corruption when you attempt to use your recovered pointers.
The ARC documentation describes the various bridge casts and when to use them. However given your comment on memory use consider very carefully whether you should be doing this.
HTH
Addendum: Comment followup
You are misunderstanding how memory addresses, object lifetime, etc. work in (Objective-)C. I would strongly recommend you do not attempt to use any bridge casts until you have figured this out. Let's see if I can help you understand, with the help of an analogy or two.
Warning: Analogies always break down at some point, you should not push them too far and I'll try not to!
Let's look at your comment, it starts:
sizeof(long) = 8, sizeof(NSString)?-->"can't apply 'sizeof' to the class NSString".
You are correct that in Objective-C taking the sizeof of a class type is disallowed, but that is not what the issue is here. Look at the code in your question:
NSString *mice = #"dogs eat cats";
long dog = (long)mice;
Here you are not operating on a value of type NSString but on one of type NSString * - these two are very different.
Instead of considering NSString which is an object type in Objective-C think of a real world analogy: a building. In this analogy what is the equivalent of an object reference, such as NSString *? It is the address of the building.
Is a building address the same kind of thing as a building? No. Is it the same size as a building? No. You can write the address on a piece of paper and put it in your pocket. You can't put a building in your pocket (unless you are Gulliver ;-)). You can even put your piece of paper with an address on it inside a building, it fits easily.
What the address of a building does is enable to you locate the building, but it doesn't guarantee that there is a building at the address - it could have been demolished, and may have been replaced by a new building with a different purpose.
This is analogous to the address of an object, it enables you to locate the object, but is does not guarantee the object exists – it could have been destroyed, and its old location could now be part of some other object.
The comparison you were after is what is sizeof(long) compared to sizeof(NSString *). On current 64-bit Objective-C you'll find both of these result on 8.
Note: on the (rare) occasions you need to store an address in a integer you should not use the type long, rather you should use the type intptr_t which is a standard C integer type of the same size as an address. So your code should really have been:
NSString *mice = #"dogs eat cats";
intptr_t dog = (intptr_t)mice;
(That said, you probably shouldn't have written this code at all.)
Back to your comment, you continue:
But in it's place as an example, if I were to create a structure of 4 longs... the sizeof(struct4longs) = 32. Lets say you have a structure that takes 1mb of ram. Under ARC using their rules, to keep the reference, I would allocate 1mb to keep the reference to the 1mb... because the old way of referencing(keeping only addresses) is no longer allowed-->NSString *appled = (NSString *)dog;
No, no, no. An address is the same size regardless of what it references.
In our analogy of buildings the addresses "330 5th Ave, New York" and "350 5th Ave, New York" are exactly the same size. The first is a Panera Bread cafe, the second is the Empire State Building – the buildings are not the same size!
Converting an object address to an integer does not save any space at all.
The difference between pre-ARC and post-ARC
Sticking with our analogy: In pre-ARC times buildings were built (alloc/init, new, etc.), marked as in use (retain), marked as no longer required (release), and eventually demolished (object destruction) manually.
A building could be left empty and unused and it just stood there, using up space, unless the builder (programmer) came along and demolished it (the programmer matches a release for every retain).
You could write the address of a building in your address book (store its address in a pointer-typed variable such as NSString *), it did not have any effect on the lifetime of the building.
You could keep an obscured copy of the building address, say write it in code and put it in your calendar (the equivalent of you placing an object address in an integer typed variable), it still had no effect on the lifetime of the building.
So in the pre-ARC days your scheme "worked" – in that you could hide and recover object addresses – but it had no real purpose, it didn't save any space, just made your code harder to understand and more error prone. You had to use manual calls (retain, release) to control the lifetime of your objects.
The post-ARC world changes all this.
In the post-ARC world building demolition was taken over by an automatic robotic system, buildings no longer in use are demolished. No action required by humans (programmers).
So how does the robotic system know when a building can be demolished?
Coloured paper! (I do not joke, but remember this is an analogy)
The rule is simple: write down the address of a building on a piece of yellow paper and the robot demolition crew will not demolish the building.
Get an eraser and rub out the buildings name from every piece of yellow paper it is on and the robot crew will, at some time of their choosing, move in and demolish it.
Same thing happens if you throw away or burn the piece of yellow paper. Only yellow paper owned by someone is considered by the robot demolition crew. (This includes yellow paper found inside buildings provided the address of that building is written down on a piece of yellow paper, and if that piece of yellow paper is in a building then that building's address is written on another piece of yellow paper... etc., and provided at some point there is a piece of yellow paper not in a building which starts the chain off.)
Write the address on a piece of white paper and the robots just ignore the piece of paper. Only owned yellow paper prevents the building being destroyed.
What your old pre-ARC code does in the the new post-ARC world is transfer the address of a building from a yellow piece of paper to a white piece, and then throws aways the yellow piece. Not good when there is an eager robot demolition crew looking to demolish buildings out there.
Later you try to copy the address from your white piece of paper back onto a yellow piece in the hope that the robots haven't found the building yet... hopes get dashed, that's life. Left something important in the building? A priceless work of art maybe left hanging on the wall? Tough.
Enough analogy, back to Objective-C:
The yellow pieces of paper are technically called strong references, a variable of object type (e.g. NSString *) in the post-ARC world is (usually, the few exceptions can be ignored at this point) implicitly marked as strong (e.g. __strong NSString *).
The white pieces of paper are all non-object pointer typed variables (e.g. long, intptr_t, and even int * etc.) and object pointer typed variables explicitly marked as __unsafe_unretained – that name should tell you everything, storing an address only in any such variable is unsafe as the object will not be retained, the automatic object reclamation will destroy it.
Conclusion:
Do not do what you were doing in the pre-ARC days.
In those days it saved no memory and had no useful purpose, however it wasn't unsafe.
In the post-ARC days it not only has no useful purpose, it is unsafe.
Just store your addresses as addresses.
You might wonder why bridging casts exist. Well there are special cases where they are needed, they are not for general use. When, and if, you get to those cases you'll read about them and how to use them safely.
I hope the above helps you sort this out!
You need to cast it to void * first:
NSString *appled = (__bridge NSString *)((void *)dog);
Updated. Because of down votes on this post I need to add a warning: Obj-C is flexible enough to let you fix such kind of compiler errors, but if you tying to do so - you need to be completely sure what you are doing and why.
Storing object pointer in non-object type will act like __unsafe_unretained variable.
__unsafe_unretained specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong
references to the object. If the object it references is deallocated,
the pointer is left dangling. (source)
So even if you need to make such type casts (for any reason), and you want your object to be valid - you need to ensure that this object has at least one strong reference.
And in case if you don't want to keep strong references to original object, you can count references by yourself using __bridge_retained and __bridge_transfer
NSString *mice = #"dogs eat cats";
long dog = (long)(__bridge_retained CFTypeRef)mice;
// here original mice object has retain count +1
NSString *appled = (__bridge_transfer NSString *)((void *)dog);
// here __bridge_transfer decreased previously gained retain count by 1

Do I need to use autorelease on object which created not using alloc init? [duplicate]

I'm just beginning to have a look at Objective-C and Cocoa with a view to playing with the iPhone SDK. I'm reasonably comfortable with C's malloc and free concept, but Cocoa's references counting scheme has me rather confused. I'm told it's very elegant once you understand it, but I'm just not over the hump yet.
How do release, retain and autorelease work and what are the conventions about their use?
(Or failing that, what did you read which helped you get it?)
Let's start with retain and release; autorelease is really just a special case once you understand the basic concepts.
In Cocoa, each object keeps track of how many times it is being referenced (specifically, the NSObject base class implements this). By calling retain on an object, you are telling it that you want to up its reference count by one. By calling release, you tell the object you are letting go of it, and its reference count is decremented. If, after calling release, the reference count is now zero, then that object's memory is freed by the system.
The basic way this differs from malloc and free is that any given object doesn't need to worry about other parts of the system crashing because you've freed memory they were using. Assuming everyone is playing along and retaining/releasing according to the rules, when one piece of code retains and then releases the object, any other piece of code also referencing the object will be unaffected.
What can sometimes be confusing is knowing the circumstances under which you should call retain and release. My general rule of thumb is that if I want to hang on to an object for some length of time (if it's a member variable in a class, for instance), then I need to make sure the object's reference count knows about me. As described above, an object's reference count is incremented by calling retain. By convention, it is also incremented (set to 1, really) when the object is created with an "init" method. In either of these cases, it is my responsibility to call release on the object when I'm done with it. If I don't, there will be a memory leak.
Example of object creation:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Now for autorelease. Autorelease is used as a convenient (and sometimes necessary) way to tell the system to free this object up after a little while. From a plumbing perspective, when autorelease is called, the current thread's NSAutoreleasePool is alerted of the call. The NSAutoreleasePool now knows that once it gets an opportunity (after the current iteration of the event loop), it can call release on the object. From our perspective as programmers, it takes care of calling release for us, so we don't have to (and in fact, we shouldn't).
What's important to note is that (again, by convention) all object creation class methods return an autoreleased object. For example, in the following example, the variable "s" has a reference count of 1, but after the event loop completes, it will be destroyed.
NSString* s = [NSString stringWithString:#"Hello World"];
If you want to hang onto that string, you'd need to call retain explicitly, and then explicitly release it when you're done.
Consider the following (very contrived) bit of code, and you'll see a situation where autorelease is required:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:#"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
I realize all of this is a bit confusing - at some point, though, it will click. Here are a few references to get you going:
Apple's introduction to memory management.
Cocoa Programming for Mac OS X (4th Edition), by Aaron Hillegas - a very well written book with lots of great examples. It reads like a tutorial.
If you're truly diving in, you could head to Big Nerd Ranch. This is a training facility run by Aaron Hillegas - the author of the book mentioned above. I attended the Intro to Cocoa course there several years ago, and it was a great way to learn.
If you understand the process of retain/release then there are two golden rules that are "duh" obvious to established Cocoa programmers, but unfortunately are rarely spelled out this clearly for newcomers.
If a function which returns an object has alloc, create or copy in its name then the object is yours. You must call [object release] when you are finished with it. Or CFRelease(object), if it's a Core-Foundation object.
If it does NOT have one of these words in its name then the object belongs to someone else. You must call [object retain] if you wish to keep the object after the end of your function.
You would be well served to also follow this convention in functions you create yourself.
(Nitpickers: Yes, there are unfortunately a few API calls that are exceptions to these rules but they are rare).
If you're writing code for the desktop and you can target Mac OS X 10.5, you should at least look into using Objective-C garbage collection. It really will simplify most of your development — that's why Apple put all the effort into creating it in the first place, and making it perform well.
As for the memory management rules when not using GC:
If you create a new object using +alloc/+allocWithZone:, +new, -copy or -mutableCopy or if you -retain an object, you are taking ownership of it and must ensure it is sent -release.
If you receive an object in any other way, you are not the owner of it and should not ensure it is sent -release.
If you want to make sure an object is sent -release you can either send that yourself, or you can send the object -autorelease and the current autorelease pool will send it -release (once per received -autorelease) when the pool is drained.
Typically -autorelease is used as a way of ensuring that objects live for the length of the current event, but are cleaned up afterwards, as there is an autorelease pool that surrounds Cocoa's event processing. In Cocoa, it is far more common to return objects to a caller that are autoreleased than it is to return objets that the caller itself needs to release.
Objective-C uses Reference Counting, which means each Object has a reference count. When an object is created, it has a reference count of "1". Simply speaking, when an object is referred to (ie, stored somewhere), it gets "retained" which means its reference count is increased by one. When an object is no longer needed, it is "released" which means its reference count is decreased by one.
When an object's reference count is 0, the object is freed. This is basic reference counting.
For some languages, references are automatically increased and decreased, but objective-c is not one of those languages. Thus the programmer is responsible for retaining and releasing.
A typical way to write a method is:
id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;
The problem of needing to remember to release any acquired resources inside of code is both tedious and error-prone. Objective-C introduces another concept aimed at making this much easier: Autorelease Pools. Autorelease pools are special objects that are installed on each thread. They are a fairly simple class, if you look up NSAutoreleasePool.
When an object gets an "autorelease" message sent to it, the object will look for any autorelease pools sitting on the stack for this current thread. It will add the object to the list as an object to send a "release" message to at some point in the future, which is generally when the pool itself is released.
Taking the code above, you can rewrite it to be shorter and easier to read by saying:
id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;
Because the object is autoreleased, we no longer need to explicitly call "release" on it. This is because we know some autorelease pool will do it for us later.
Hopefully this helps. The Wikipedia article is pretty good about reference counting. More information about autorelease pools can be found here. Also note that if you are building for Mac OS X 10.5 and later, you can tell Xcode to build with garbage collection enabled, allowing you to completely ignore retain/release/autorelease.
Joshua (#6591) - The Garbage collection stuff in Mac OS X 10.5 seems pretty cool, but isn't available for the iPhone (or if you want your app to run on pre-10.5 versions of Mac OS X).
Also, if you're writing a library or something that might be reused, using the GC mode locks anyone using the code into also using the GC mode, so as I understand it, anyone trying to write widely reusable code tends to go for managing memory manually.
As ever, when people start trying to re-word the reference material they almost invariably get something wrong or provide an incomplete description.
Apple provides a complete description of Cocoa's memory management system in Memory Management Programming Guide for Cocoa, at the end of which there is a brief but accurate summary of the Memory Management Rules.
I'll not add to the specific of retain/release other than you might want to think about dropping $50 and getting the Hillegass book, but I would strongly suggest getting into using the Instruments tools very early in the development of your application (even your first one!). To do so, Run->Start with performance tools. I'd start with Leaks which is just one of many of the instruments available but will help to show you when you've forgot to release. It's quit daunting how much information you'll be presented with. But check out this tutorial to get up and going fast:
COCOA TUTORIAL: FIXING MEMORY LEAKS WITH INSTRUMENTS
Actually trying to force leaks might be a better way of, in turn, learning how to prevent them! Good luck ;)
Matt Dillard wrote:
return [[s autorelease] release];
Autorelease does not retain the object. Autorelease simply puts it in queue to be released later. You do not want to have a release statement there.
My usual collection of Cocoa memory management articles:
cocoa memory management
There's a free screencast available from the iDeveloperTV Network
Memory Management in Objective-C
NilObject's answer is a good start. Here's some supplemental info pertaining to manual memory management (required on the iPhone).
If you personally alloc/init an object, it comes with a reference count of 1. You are responsible for cleaning up after it when it's no longer needed, either by calling [foo release] or [foo autorelease]. release cleans it up right away, whereas autorelease adds the object to the autorelease pool, which will automatically release it at a later time.
autorelease is primarily for when you have a method that needs to return the object in question (so you can't manually release it, else you'll be returning a nil object) but you don't want to hold on to it, either.
If you acquire an object where you did not call alloc/init to get it -- for example:
foo = [NSString stringWithString:#"hello"];
but you want to hang on to this object, you need to call [foo retain]. Otherwise, it's possible it will get autoreleased and you'll be holding on to a nil reference (as it would in the above stringWithString example). When you no longer need it, call [foo release].
The answers above give clear restatements of what the documentation says; the problem most new people run into is the undocumented cases. For example:
Autorelease: docs say it will trigger a release "at some point in the future." WHEN?! Basically, you can count on the object being around until you exit your code back into the system event loop. The system MAY release the object any time after the current event cycle. (I think Matt said that, earlier.)
Static strings: NSString *foo = #"bar"; -- do you have to retain or release that? No. How about
-(void)getBar {
return #"bar";
}
...
NSString *foo = [self getBar]; // still no need to retain or release
The Creation Rule: If you created it, you own it, and are expected to release it.
In general, the way new Cocoa programmers get messed up is by not understanding which routines return an object with a retainCount > 0.
Here is a snippet from Very Simple Rules For Memory Management In Cocoa:
Retention Count rules
Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.
Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased.
Implement a -dealloc method to release the instancevariables you own
The 1st bullet says: if you called alloc (or new fooCopy), you need to call release on that object.
The 2nd bullet says: if you use a convenience constructor and you need the object to hang around (as with an image to be drawn later), you need to retain (and then later release) it.
The 3rd should be self-explanatory.
Lots of good information on cocoadev too:
MemoryManagement
RulesOfThumb
As several people mentioned already, Apple's Intro to Memory Management is by far the best place to start.
One useful link I haven't seen mentioned yet is Practical Memory Management. You'll find it in the middle of Apple's docs if you read through them, but it's worth direct linking. It's a brilliant executive summary of the memory management rules with examples and common mistakes (basically what other answers here are trying to explain, but not as well).

Can we release some memory in Objective-c that a variable does not own but points to?

I have some code like this:
NSObject *var1 = [[NSObject alloc] init];
NSObject *var2 = var1;
[var2 release];
var1 = nil;
Is this correct or is this a memory leak?
As far as I know only var1 can release the memory alloc-inited in the first line, as per the Object Ownership policy
Your code will release the memory, because there is a single alloc, and a single release - the amount of pointers to the object is not a factor.
Ownership is a concept that the Object Ownership policy talks about because if you follow the guidelines it makes it easier to manage and ultimately prevent problems relating to releasing things you shouldn't release (or not releasing things you should).
Your code is all right and doesn't leak. But it seems like you don’t really understand pointers. A pointer can not own another object, it is just a reference that tells the computer which object is being accessed. In the reference-counted memory model of Cocoa it doesn’t matter at all how many pointers point to a single object.
You really should learn C (especially about pointers) before you try to learn Objective-C.
Your example will not result in a memory leak as var1 and var2 point to the same object in memory—thus the alloc call has a matching release. If the NSObject was retained as it was assigned to var2 however, there would be a memory leak as there would be no matching release.
When the memory management guide talks about the concept of ownership, it doesn't mean that a variable (e.g. var1) owns an object; it's more about what "scope" owns it (e.g. a class or method). In your example, the method containing those statements would be responsible for releasing the object.
It's the object that keeps a reference count, not the pointer to the object. If you have a dozen pointers to an object, you could use any one of them to release the object because they're all pointing to the same object. However, it's a lot easier to follow your code and make sure that you don't have memory management problems if you don't play those sorts of games.

Objective C / Object Orientated Pointers

I have been playing with objective C a little and am finding it a great language..
Coming from C# i found pointers a little hard but now i understand the concept and how to use them..
ie:
MyObject* x = [[myObject alloc] callinitializer];
which create a new object on the heap and a pointer on the stack..
but can somebody please explain why to access the objects properties you do this:
[x setsomeprop: #"I Like Pizza"];
instead of this:
[*x setsomeprop: #"With Pineapple"];
without the dereferencing star arent we just working with the pointer instead of the object itself??
Confuesd!
Thanks
Daniel
No. The bracket syntax is a language feature specifically for objects - it dereferences the pointer automatically.
Partly this is just a result of how method dispatch works in a dynamic language like Objective-C. There's almost nothing useful you can do with a dereferenced object pointer in Objective-C.
Given that all objects are stored on the heap, and manage their own lifecycle with retain/release (or via garbage collection), a pointer to the object is exactly what you want to use in 99% of all situations.
As it turns out, essentially the same mechanism is used in C# and Java - object references are pointers, which is why assigning one reference to another makes them point at the same object, rather than copying the object.

Pointers, am I using them correctly? Objective-c/cocoa

I have this in my #interface
struct track currentTrack;
struct track previousTrack;
int anInt;
Since these are not objects, I do not have to have them like int* anInt right?
And if setting non-object values like ints, boolean, etc, I do not have to release the old value right (assuming non-GC environment)?
The struct contains objects:
typedef struct track {
NSString* theId;
NSString* title;
} *track;
Am I doing that correctly?
Lastly, I access the struct like this:
[currentTrack.title ...];
currentTrack.theId = #"asdf"; //LINE 1
I'm also manually managing the memory (from a setter) for the struct like this:
[currentTrack.title autorelease];
currentTrack.title = [newTitle retain];
If I'm understanding the garbage collection correctly, I should be able to ditch that and just set it like LINE 1 (above)?
Also with garbage collection, I don't need a dealloc method right?
If I use garbage collection does this mean it only runs on OS 10.5+? And any other thing I should know before I switch to garbage collected code?
Sorry there are so many questions. Very new to objective-c and desktop programming.
Thanks
I have this in my #interface
struct track currentTrack;
struct track previousTrack;
int anInt;
Since these are not objects, I do not have to have them like int* anInt right?
That would declare a pointer to an int stored somewhere else.
And if setting non-object values like ints, boolean, etc, I do not have to release the old value right (assuming non-GC environment)?
release is a message. You can only send a message to a Cocoa (or, in some cases, Core Foundation) object.
The struct contains objects:
typedef struct track {
NSString* theId;
NSString* title;
More precisely, it contains pointers to objects.
You can't ever have an object stored directly in a variable; you can only allocate it dynamically by sending an alloc message to a class, and receive the pointer to the allocated instance. Similarly, you can only send a message to a pointer to an object; you cannot and should not dereference a pointer to an object.
For these reasons, we almost always elide the “a pointer to”. We speak of the pointers as if they are the objects, but, in precise truth, they are not.
} *track;
That's correct if you want to declare the track type as being a pointer to a struct track. Generally, this will confuse people.
Lastly, I access the struct like this:
[currentTrack.title ...];
currentTrack.theId = #"asdf"; //LINE 1
So the previous line is line 0? ;)
I'm also manually managing the memory (from a setter) for the struct like this:
[currentTrack.title autorelease];
currentTrack.title = [newTitle retain];
If I'm understanding the garbage collection correctly, I should be able to ditch that and just set it like LINE 1 (above)?
If you're using garbage collection, then the autorelease and retain messages will do nothing, so yes, the plain assignment and the assignment with (ineffectual) release and retain messages are equivalent.
I do question why you're putting this information in a structure and not a model object, though.
Also with garbage collection, I don't need a dealloc method right? If I use garbage collection does this mean it only runs on OS 10.5+? And any other thing I should know before I switch to garbage collected code?
Yes: Read the Garbage Collection Programming Guide. It tells you everything you need to know, including the answers to the previous two questions.
As for pointers, you may want to read my pointers tutorial. The title says C, but everything in C is also true in Objective-C.
Although you seem to understand this stuff all right in general, I'd strongly recommand against storing objects in a struct. Getting proper memory management for that will be very troublesome — because even though the struct itself doesn't require memory management, the objects still do, and unless the struct is only ever accessed through a function API (essentially making it s poor man's object), you're going to have a tough time ensuring that happens. Like Peter said, that makes sense to be a model object.
Correct, correct, no, yes, correct, yes, and Apple's Garbage Collection Programming Guide is a good read.