我想编写一个没有Cocoa或GNU Object.h
的Objective-C类(用于教育目的)。我在网上挖掘,在我看来,很多人希望“随语言而来”的东西,例如类和消息发送,实际上是由第三方编写的文件中定义的,例如{{1} }。
是否有关于什么是真正纯Objective-C以及什么是运行时/框架的一部分的文档?我需要实现哪些功能才能在不使用任何第三方代码(如objc-runtime.h
或Object.h
的情况下获得工作环境(请再次注意,这是出于教育目的,而不是用于生产代码)?< / p>
感谢您的任何见解!
答案 0 :(得分:5)
真的,如果你不从NSObject
继承,那么唯一必须照顾自己的是对象创建和破坏;无论其父类如何,否则方法的行为方式相同。 KVC和内存管理等功能是OpenStep / Cocoa的功能,但不是语言的一部分。
这是一个从头开始的课程:
@interface MyClass { // note the lack of a superclass here
@private Class isa;
}
+ (MyClass *)create;
- (void)destroy;
- (int)randomNumber;
@end
@implementation MyClass
+ (MyClass *)create {
return class_createInstance(self, 0);
}
- (void)destroy {
object_dispose(self);
}
- (int)randomNumber {
return rand();
}
@end
以下是它的使用方法:
int main(int argc, char **argv) {
MyClass *foo = [MyClass create];
if (foo) {
printf("random! %i\n", [foo randomNumber]);
[foo destroy];
}
}
修改:如果您甚至不想使用class_createInstance()
和object_dispose()
,则必须手动实现等效项,以及等效的{{} 1}}所以你知道一个对象占用了多少内存。但即使你管理它,也不要认为你已经逃脱了Objective-C运行时!消息调度仍然完全基于运行时中的C函数构建,并且Objective-C语法在编译期间转换为对这些函数的调用。
答案 1 :(得分:2)
Matt Gallagher写了一篇真正的cool post来编写一个简单的Cocoa程序。由于Objective-C是C的超集,你可以这样做:
echo "int main(){return 0;}" | gcc -x objective-c -; ./a.out ; echo $?
无论如何,你可能会因阅读他的帖子而得到很多。
答案 2 :(得分:1)
就避免框架和创建自己的基础对象而言,您需要做的就是确保第一个iVar被声明为Class is_a
,并且您可能有一个合理的尝试来复制NSObject是通过通过运行时函数。
就避免运行时库和框架而言,这是不可能的。 Objective C(或者至少是不仅仅是C的位)是一种动态语言。因此,C不执行的所有操作都由运行时库处理。
有可能使用32位运行时和不推荐使用的API构建自己的类和对象,这不会抽象出类,协议等的布局到现代运行时的范围(我是只是真的用现代运行时来探讨)
也许你可以创建类,添加方法和分配实例,并通过在class_t结构中设置值然后使用malloc()进行分配,尽管如此,你仍然会在每次使用时隐式使用运行时函数objc_msgSend [obj selector]
语法 - 除非你想要实现它,在这种情况下你只是自己重新实现了语言。您正在寻找语言的“纯核心”只是运行时。
答案 3 :(得分:1)
这是一个类的示例,不使用class_createInstance或object_dispose,或任何其他Objective-C运行时(至少我们不直接调用它们)。
#import <objc/objc.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
static Class __scratchClass = NULL;
@interface Scratch {
Class isa;
char *name;
}
+ (id) initialize;
+ (Scratch*) new:(const char*)strName;
- (void) sayHello;
- (void) destroy;
@end
@implementation Scratch
+ (id) initialize {
__scratchClass = self;
return self;
}
+ (Scratch*) new:(const char*) strName {
Scratch* pObj = (Scratch*)malloc(sizeof(Scratch));
if (!pObj) return NULL;
memset(pObj, 0, sizeof(Scratch));
pObj->isa = __scratchClass;
pObj->name = (char*)malloc(strlen(strName)+1);
strcpy(pObj->name, strName);
return pObj;
}
- (void) sayHello {
printf("Hello, World!\nThis is Scratch (%s)...\n", name);
}
- (void) destroy {
if (name) {
free(name);
name = NULL;
}
free(self);
}
@end
int main(int argc, char** argv) {
Scratch* ps = [Scratch new:argv[0]];
[ps sayHello];
[ps destroy];
return 0;
}
编译代码(假设您将其保存为'test1.m'):
gcc -o test1 test1.m -lobjc