3
votes

I am testing some simple Objective-C code on Windows (cygwin, gcc). This code already works in Xcode on Mac. I would like to convert my objects to not subclass NSObject (or anything else, lol). Is this possible, and how?

What I have so far:

// MyObject.h
@interface MyObject

- (void)myMethod:(int) param;

@end

and

// MyObject.m
#include "MyObject.h"

@interface MyObject()
{ // this line is a syntax error, why?
    int _field;
}
@end

@implementation MyObject

- (id)init {
  // what goes in here?
    return self;
}

- (void)myMethod:(int) param {
  _field = param;
}

@end

What happens when I try compiling it:

gcc -o test MyObject.m -lobjc
MyObject.m:4:1: error: expected identifier or ‘(’ before ‘{’ token
MyObject.m: In function ‘-[MyObject myMethod:]’:
MyObject.m:17:3: error: ‘_field’ undeclared (first use in this function)

EDIT My compiler is cygwin's gcc, also has cygwin gcc-objc package:

gcc --version
gcc (GCC) 4.7.3

I have tried looking for this online and in a couple of Objective-C tutorials, but every example of a class I have found inherits from NSObject. Is it really impossible to write Objective-C without Cocoa or some kind of Cocoa replacement that provides NSObject?

(Yes, I know about GNUstep. I would really rather avoid that if possible...)

EDIT This works:

// MyObject.h
@interface MyObject
@end
// MyObject.m
#include "MyObject.h"
@implementation MyObject
@end

Not very useful though...

2
Possibly useful: stackoverflow.com/questions/6203467/… , stackoverflow.com/questions/4295317/… (note that in this question the new root class still implements the NSObject protocol) - user2864740
Thanks! Does that mean there is no way to allocate an object without using NSObject, even? Argh... what a screwy language. I don't want to interact with the runtime, or any libraries, I just want to run a completely self-contained, simple piece of code. I guess I can write it in plain C and just call that a .m file, haha. - Alex I
Ivars in categories is a Clang-only feature, unless GCC has added it in the very recent past. You need a runtime library, for message dispatch if absolutely nothing else, no matter what you want to do about a root class. The GNU libobjc is part of with GNUStep; I don't know if they're seperable, but they might be. - jscs
You do need message dispatch. That's the fundamental mechanism of Objective-C [[MyObject alloc] init] contains two message dispatches. You need objc_msgSend(). It may be that your compiler is including libobjc automatically when you compile an ObjC source, unbeknownst to you. - jscs
Unfortunately for you, there just aren't many people writing ObjC code for platforms other than Apple's. In theory it's a portable language, because it's just a layer on top of C, but that layer itself has to be ported. I'd suggest looking at either GNUStep's or Apple's root classes for info. (A note; when I said "categories" above, I meant "extensions", which may also not be available via GCC.) - jscs

2 Answers

2
votes

It's possible to make classes without a base class. There are a couple of things going on. First, your compiler doesn't seem to like the "()" class extension syntax. Other compilers would be OK with it. If you remove those "()" on line four of MyObject.m then your compiler will complain that you've got two duplicate interfaces for the MyObject class. For the purpose of your test you should move that _field variable into the declaration of MyObject in the header file, like:

@interface MyObject {
    int _field;
}
-(void)myMethod:(int)param;
@end

Then you can completely remove that extra @interface in the .m file. That should get you started at least.

2
votes

It's possible, but note that NSObject implements the memory allocation API in objective-c, and if you don't implement NSObject's +alloc and -dealloc or equivalent on a root class, you'll still need to implement the same functionality for every class.