Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's required to implement root class of Objective-C?

I tried this code:

// main.m
#import <stdio.h>

@interface Test 
+ (void)test;
@end
@implementation Test
+ (void)test
{
    printf("test");
}
@end

int main()
{
    [Test test];
    return  0;
}

with LLVM/Clang without any framework, it doesn't compiled with this error:

Undefined symbols:
  "_objc_msgSend", referenced from:
      _main in main.o
ld: symbol(s) not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So I added libobjc.dylib. Code compiled, but threw this runtime exception:

objc[13896]: Test: Does not recognize selector forward::
Program received signal:  “EXC_BAD_INSTRUCTION”.

#0  0x9932a4b4 in _objc_error
#1  0x9932a4ea in __objc_error
#2  0x993212b6 in _objc_msgForward
#3  0x99321299 in _objc_msgForward
#4  0x99321510 in _class_initialize
#5  0x99328972 in prepareForMethodLookup
#6  0x99329c17 in lookUpMethod
#7  0x99321367 in _class_lookupMethodAndLoadCache
#8  0x99320f13 in objc_msgSend
#9  0x00001ee5 in start

I realized some implementation required for root class, but I don't know what should I do next. What's required to make a new root class? And is there any specification for this?

like image 725
eonil Avatar asked Aug 27 '10 07:08

eonil


1 Answers

I just came to this question because I had the same "academic" question. After working through it a bit, I have found that the other answers to this question aren't completely correct.

It is true that on the Apple Objective-C 2.0 runtime, you must implement certain methods in order for your code to work. There is actually only one method that you need to implement: the class method initialize.

@interface MyBase 
+ (void)test;
@end
@implementation MyBase
+ (void)initialize {}
+ (void)test {
 // whatever
}
@end

The runtime will automatically call initialize when you first use your class (as explained in Apple's documentation). Not implementing this method is the reason for the message forwarding error.

Compiling with clang test.m -Wall -lobjc (or gcc) will allow you to call the class method test without any issue. Making object allocation work is a different story. At the very least, you'll need an isa pointer on your base class if you're using instance variables. The runtime expects this to be there.

like image 142
wbyoung Avatar answered Sep 27 '22 20:09

wbyoung