程序猿可能没见过猪跑,但必定会认识”hello world”, 不论是教科书还是各种入门教程,都是以hello world来开始一门新语言的学习,ObjC也不例外。在ObjC的世界里,第一眼见到的可能是如下内容:

int main(int argc, const char * argv[]) {
    NSLog(@"hello world");
    return 0;
}

学过C语言的应该都比较清楚这其中的各面,唯一困惑的应该是@符号,这是何物?为何需要在字符串加上@???心中不免留下千万个问号。那么我们讲为你一一解开谜底。

从函数声明理解

通过查找官方API可以发现NSLog的声明:

void NSLog(NSString *format, ...)

从以上函数声明可以看出实参@"hello world"应该是个NSString类型,于是我们推断出此处@的作用应该是将char字符串转换为NSString,即编译器编译时将@带的字符串转化为NSString.

从C语言角度理解

大家都知道C中是没有对象的概念,只有结构体这一说,那么如何实现的呢?下面我将为你还原真相,在此之前先学习下如何将.m文件还原成.cpp文件.

clang -rewrite-objc main.m

通过以上方式,就可以将objc转化成cpp. 针对上述的hello world我们可以得到如下文件内容:(这里只列出重要内容)

...

struct __NSConstantStringImpl {
  int *isa;
  int flags;
  char *str;
  long length;
};

...

static __NSConstantStringImpl __NSConstantStringImpl__var_folders_ls_0tjr4wp56kxgjwjr9l2qfjw00000gp_T_main_078c9f_mi_0 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"hello world",11};

...

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_ls_0tjr4wp56kxgjwjr9l2qfjw00000gp_T_main_078c9f_mi_0);
    }
    return 0;
}

...