从头开始编写Objective-C类

问题描述

| 我想编写一个没有Cocoa或GNU的
Object.h
(出于教育目的)的Objective-C类。我在网上挖了东西,在我看来,很多人期望“用这种语言来”,例如类和消息发送,实际上是在第三方编写的文件中定义的,例如“ 1”。 是否有关于什么是真正的Objective-C以及运行时/框架的一部分的文档?在不使用任何第三方代码(例如
Object.h
objc-runtime.h
)的情况下,我必须实现什么功能才能获得工作环境(再次注意,这是出于教育目的,而不是生产代码)? 感谢您的见解!     

解决方法

        确实,如果您不从ѭ4继承,您唯一需要照顾的就是对象的创建和销毁。否则,方法无论其父类如何,其行为都相同。像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()
,则必须手动实现等效项以及
class_getInstanceSize()
等效项,以便您知道一个对象占用了多少内存。但是,即使您能做到这一点,也不要认为您逃脱了Objective-C运行时!消息分发仍然完全在运行时基于C函数构建,并且在编译过程中将Objective-C语法转换为对这些函数的调用。     ,        马特·加拉格尔(Matt Gallagher)写了一篇非常酷的文章,介绍了如何编写准系统可可程序。由于Objective-C是C的超集,因此您可以执行以下操作:
echo \"int main(){return 0;}\" | gcc -x objective-c -; ./a.out ; echo $?
无论如何,您可能会从阅读他的帖子中学到很多东西。     ,        至于避免使用框架并创建自己的基础对象,您要做的就是确保将第一个iVar声明为“ 11”,并且通过传递给运行时函数,您可能在复制NSObject方面有一个合理的选择。 至于避免运行时库和框架运行,那实际上是不可能的。目标C(或至少是不只是C的位)是一种动态语言。因此,C所做的几乎所有工作都由运行时库处理。 可能可以使用32位运行时和不推荐使用的API来构建自己的类和对象,这不会像现代运行时那样抽象化类,协议等的布局(我只真正与现代运行时戳了一下) 也许您可以创建类,添加方法并分配实例,并通过在class_t结构中设置值,然后使用malloc()进行分配,尽管即便如此,每次使用
[obj selector]
语法时,您仍将隐式使用运行时函数objc_msgSend -除非您也想实现它,在这种情况下,您只是自己重新实现了该语言。您正在寻找的语言的“纯粹核心”就是运行时。     ,        这是一个类的示例,没有使用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,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