Brew me up a hot cup of Cocoa

Moderator
Posts: 133
Joined: 2008.05
Post: #1
In my ongoing quest to piss off the democratic party, I've decided to learn Cocoa so that one day I can design a nudity mod in Cocoa-Java and release it to Hillary Clinton, and I can cleverly title it Cocoa-Java-Coffee mod. Brilliant.

But seriously, I decided to learn Objective-C and the Cocoa API. I went through the tutorial and created my first Cocoa app in Obj-C, that was a good 2 hours spent because I'm overly critical of detail. Anyway, the explanations on the Apple site explain Cocoa/Obj-C like I would explain to a four year old, and all I want to do is learn the distinctions between using Carbon with C++ and Cocoa with Obj-C. Mostly, where it's ok to put in C++ style code and where I have to use Objective-C.

So, I'm going to throw a few things out there, and you all just correct me if I'm wrong.
1. The interface builder takes care of mostly everything, as long as I use it correctly. I should only design classes from a blank page if they are not connected directly to the interface of the application. Also, if I'm designing a class that is doing something that doesn't involve a Cocoa control or Window, I don't need to put an instance of it in my Interface Builder palette.

2. All classes must be defined in the Objective-C way, a .h and a .m, the crazy looking Java style way. I can't make a .h and a .cpp and do something like:
Code:
class Foo
{
public:
Foo();
~Foo();
private:
int iHeartData;
};
Foo::Foo()
{
}

3. I cannot call member functions like I do in C++, I must use the Obj-C syntax of [instance method:arg];

4. I can interchange the position of arguments with Obj-C, because if I have a function
- (id)doSomething:(int)withInt and:(float)withFloat;
I can call it as
float x;
int y;
id someData = [instance and:x doSomething:y];

I'm sure I have more, but I'll continue reading. Anyone that knows of a great C++ -> Obj-C tutorial would have my utmost gratitude, and I'm not buying a book, because I can't even pay for rent.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
4. is incorrect.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #3
Where did you 4 come from? ive never heard of that and it doesnt work.
1 Gives me an Idea, I wonder to what extent you could build fully working applications with no programming at all in interface builder if the right palletes were made, any ideas on this?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #4
5. Using any of the NS classes, or any classes derived from NS classes, I should use [[obj alloc] init], since that is the functionality I derive from a NS class. If I create my own classes, without any inheritance, I'm free to use new and delete, but to stay consistent I should write alloc and init functions for them. For any primitive types, I should use new and delete.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
5. just sounds really confused.

a) C++ classes and ObjC classes have nothing to do with each other, work in completely different ways, and are not compatible in any way, shape or form.
b) By Cocoa convention, methods that begin with "init" are a rough analog to C++ constructors. Cocoa's [[Foo alloc] init.............]; is approximately equivalent to C++'s new Foo(.........);.
c) Your ObjC classes should always inherit from something, even if that something is just NSObject.
d) Your C++ classes can do whatever the heck you would normally do, they aren't at all affected by your use of ObjC(++).
Quote this message in a reply
Member
Posts: 198
Joined: 2005.01
Post: #6
unknown Wrote:1 Gives me an Idea, I wonder to what extent you could build fully working applications with no programming at all in interface builder if the right palletes were made, any ideas on this?

With CoreData, quite a lot. There was a great tutorial on CocoaBuilder (I think that was the site?) that showed how to build a full database-driven blog app that involved zero written code.

Cryptic Allusion Games / Cryptic Allusion, LLC
http://www.cagames.com/
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #7
Zero written code, wow!
This could be good idea to get people to start programming without them knowing, have a basic toolkit for creating simple applications, then incorporate some really basic applescript elements to control slightly more complicated actions and you'l have anyone programming in no time.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 198
Joined: 2005.01
Post: #8
Oh here it is, Cocoa Dev Central:

http://www.cocoadevcentral.com/articles/000085.php

It's been a while since I went through it, but IIRC there's no code to be written to get it functional.

Cryptic Allusion Games / Cryptic Allusion, LLC
http://www.cagames.com/
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #9
That looks really smooth im definitly going to spend some time learning about that, thanks for finding that.

EDIT: DAMMIT, Mad I dont have Core Thing cos ive got a lower version of X than everyone else, this sucks and blows HARD.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 198
Joined: 2005.01
Post: #10
Heh, yeah, one of the many nifty new things in Tiger...

Cryptic Allusion Games / Cryptic Allusion, LLC
http://www.cagames.com/
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #11
Maybe I should just wait until 10.5, how many 0.1's are do they want me to pay for?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #12
edit: Nevermind this silly question, static member functions(can I call em that in Obj-C?) work a whole lot better. Left here so someone else can learn from my mistakes.

Well, this Cocoa thing is so ridicolously easy that I've already created two game tools with it. But I have a question on memory management now. Also, stop me if you see anything wrong with the rest of my implementation, or correct me if something could be more "cocoa-esque".

I have an NSArray of, let's say, ITData, which is a subclass of NSObject used to store information to game items(you know, swords, wands, fish bowls...). Within ITData, I use a mix of primitive and NSObject derived types, whatever suits the job better. Now, I am going to write this NSArray to a property list. To do that, each entry in the NSArray I turn into a NSDictionary, converting primitive types to NSNumbers and the such things. Then I can create an NSArray of the returned NSDictionary's, and simply write that using cocoa's supplied xmlData writer class, of which I forget the name at the moment.

My question is this, though, I have a function of ITData that returns an NSDictionary containing all the data in NSObject derived form, which is then used to write the data, and then needs to be destroyed after I write the file. So, say I have a variable of type int called itemStat, which I convert to a freshly allocated NSNumber, which goes into the NSDictionary. How do I deal with it's release? Can I just set it to autorelease, give it to the dictionary, and not have to worry about it again?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #13
Yes, the point of autorelease is that you can just autorelease and forget about it.

Try doing that with new and delete Wink
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #14
So in a user defined class, if I get an autoreleased object, I have to dispose of it within that class. Whereas, if I send it to an NSDictionary, the dictionary disposes it when it needs to? Or am I missing the point?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #15
An autoreleased object is, in some sense, already disposed of. If you want to keep it, you must retain it.

Cocoa objects are reference-counted; that is, they keep track of how many people have pointers to them. When you send -retain to an object, you're saying "I'm pointing to you". It increases the reference count by 1. When you send -release to an object, you're saying "I'm not pointing to you any more". It decreases the reference count by 1. When the reference count reaches 0, the object is deallocated.

Cocoa also has "autorelease pools". These are just cocoa objects which retain the objects given to them. You can think of sending -autorelease to an object as being equivalent to:

Code:
[theCurrentAutoreleasePool retainThisObject:object];
[object release];

When the autorelease pool is destroyed, it releases all the objects it had previously retained. Cocoa creates an autorelease pool before dispatching each event, and destroys it after the event is handled. Usually this is enough, but if you're working with multiple threads, or doing many allocations in a tight loop, you may need to create and destroy autorelease pools yourself.

The final thing to understand about Cocoa memory management is that when you do [[AClass alloc] init.........]; or [anObject copy..........]; or [anObject retain];, you have responsibility for releasing the object. In all other situations, you must not release the object.

A couple of common cases:

Code:
NSString *string = [NSString stringWithFormat:@"%d", 3];
// you don't own string, so mustn't release it.

Code:
NSString *string = [[NSString alloc] initWithFormat:@"%d", 3];
// you own string, so you must release it.
[string release];
// it's now gone, it no longer exists.  You mustn't use it!

Code:
NSString *string = [[NSString alloc] initWithFormat:@"%d", 3];
// you own string, so you must release it.
[string autorelease];
// remember, autorelease includes sending a release.  You no longer
// own string, so you must not release it.  It won't actually go away
// until the current autorelease pool is popped though, so you can
// still use it.

Code:
- (void)setString:(NSString *string)
{
    // you want to keep string around indefinitely, so you must take
    // ownership by retaining it.
    [string retain];
    // you must retain string before releasing myString in case string
    // and myString point to the same string, and you are the only owner.
    // In that case a hypothetical [myString release] would reduce its
    // retain count to 0, freeing it.  At that point, [string retain] is
    // too late and will probably crash.
    [myString release];
    
    myString = string;
}
Quote this message in a reply
Post Reply