views:

227

answers:

1

I understand the basic syntax of Objective-C, have installed Cygwin, and want to experiment. However i am unsure of two things: What i would import, and what the primitive type names are. Can someone help me?

+1  A: 

The only object you can inherit from is called Object. Bare in mind that this offers nowhere near the same amount of functionality as NeXTStep's or Cocoa's NSObject. Object does not even have anything like reference counting. In order to get the same sort of reference counting memory management that NSObject has you'll need to implement it yourself.

#import <objc/Object.h>

@interface MyObject : Object
{
    int retainCount;
}

- (id) retain;
- (int) retainCount;
- (void) release;
@end

@implementation MyObject

+ (MyObject *) alloc
{
    // In Cocoa, allocated objects have an implicit retain.
    MyObject *anObject = [super alloc];
    anObject->retainCount = 1;
    return anObject;
}

- (void) release
{
    retainCount--;
    if (retainCount == 0)
        [self free];
}

- (id) retain
{
    retainCount++;
    return self;
}

- (int) retainCount
{
    return retainCount;
}
@end


int main (int argc, char *argv[])
{
    MyObject *test = [[MyObject alloc] init];
    [test retain];
    [test release];
    [test release];
    // (test should be deallocated now)

    return 0;
}

When linking, you have to make sure you link with -lobjc, this is where the definition of Object lies (I think).

The other big catch is with static string instances, i.e. strings in code that appear @"like this". With the GNU runtime, static instances of strings need to have a particular ivar layout, which is:

// Let's assume that we have a protocol <MyObject> that defines all the basic methods
// like retain, release etc. In this case, these should be no-ops because the static
// string is never deallocated. In Cocoa, there is a protocol <NSObject> which provides
// the same common methods.

@interface MyStaticStringClass : Object <MyObject>
{
    char *str;
    unsigned len;
}
- (const char *) cString;
@end

@implementation MyStaticStringClass
- (void) retain
{
    return;
}

- (id) retain
{
    return self;
}

- (int) retainCount
{
    return INT_MAX;
}

- (const char *) cString
{
    return str;
}
@end

int main (int argc, char *argv[])
{
    id aString = @"Hello world!";

    fprintf (stdout, "aString has the contents: %s\n", [aString cString]);

    return 0;
}

When compiling, you can use the flag -fconstant-string-class=MyStaticStringClass. You can provide whatever methods you like for the string class but it must have only two ivars and they must be in the right order. If you don't want to use Objective-C style strings, then you don't have to define a static string class. If you do define a static string class it should be able to replicate the behaviour of your dynamic string class (i.e. string objects that are allocated during run time) so that you can use either in a given situation.

For command-line utilities and basic apps I choose not to use Cocoa or GNUstep but rather define my own classes. It has many drawbacks, but I find that object abstraction and metamorphism in Objective-C is much easier to implement than in the other languages that I program in.

dreamlax