➜ clang -c HCPerson.m
➜
➜ nm HCPerson.o
0000000000000070 t +[HCPerson canFly]
00000000000000c0 t -[HCPerson heightInMeters]
0000000000000000 t -[HCPerson init]
00000000000000e0 t -[HCPerson setHeightInMeters:]
0000000000000090 t -[HCPerson walk:andDirection:]
U _NSLog
0000000000000108 T _OBJC_CLASS_$_HCPerson
U _OBJC_CLASS_$_NSObject
00000000000003d8 T _OBJC_IVAR_$_HCPerson._heightInMeters
00000000000003d0 T _OBJC_IVAR_$_HCPerson.age
0000000000000130 T _OBJC_METACLASS_$_HCPerson
U _OBJC_METACLASS_$_NSObject
00000000000001e0 t _OBJC_SELECTOR_REFERENCES_
00000000000001e8 t _OBJC_SELECTOR_REFERENCES_.2
0000000000000258 t __OBJC_$_CLASS_METHODS_HCPerson
00000000000002c0 t __OBJC_$_INSTANCE_METHODS_HCPerson
0000000000000328 t __OBJC_$_INSTANCE_VARIABLES_HCPerson
0000000000000370 t __OBJC_$_PROP_LIST_HCPerson
0000000000000388 t __OBJC_CLASS_RO_$_HCPerson
0000000000000278 t __OBJC_METACLASS_RO_$_HCPerson
U ___CFConstantStringClassReference
U __objc_empty_cache
U _objc_msgSend
U _objc_msgSendSuper2
0000000000000158 t l_OBJC_CLASSLIST_SUP_REFS_$_
00000000000003e0 t l_OBJC_LABEL_CLASS_$
学习 MacOS App Part 1-6
前导
ObjC
hello.m
命令行编译:
CMake编译:
注:
import有点类似nodejs的import,编译器会帮你维护全局加载一起,在header中不需要#ifndef
我理解ObjC有3个层:
ARC
Foundation
取代标准C的char*,对等std::string.
一个典型的class如下:
HCPerson.h
HCPerson.m
编译:
注:
RunLoop
然后添加一个NSTimer
关于OC的语法强烈推荐Objective-C编程, 网上随便找个pdf看个1个小时就差不多了,非常好的书,不仅学习了OC,同时也完整复习标准C。有句说句,OC/Foundation要比C++/std更友好。
语法细节
include
为什么需要include, 为什么需要header? 根据#20的表述,每个.c会通过预编译一系列过程最终生成object file,所以include只是在编译过程中定义符号。换句话说,你不可以使用一个没有定义的变量或者方法,但是不需要实现,这个是链接过程所需要的。
比如main.c
gcc -c main.c -o main.o
是成功的,只是在后续的ld会报错 (symbol not found)所以header的出现只是为了提取公应式而已,你完全可以在每个c file中复制定义。
foo.c
main.c
比较合理的当然是将foo的定义提取到foo.h,但道理就是这么个道理。
本质上来说,对于linux来说后缀根本不重要,但推荐c使用.h和.c,c++使用.hpp和.cpp,用来区分c和c++的header file。
另外一个话题就是需要明确区分definition和declaration,在header中只应该保留declaration,不能放definition, 否则会导致多个object file链接的时候存在多个相同definition。
什么是声明 (declaration)?
你可以将一个.c/.cpp对应的.o(object file),看成是一个module (模块),header中应该就是存放模块需要到导出的symbol,用来做自动link。
如果你在bar这个模块中定义变量x,
extern int x;
, 那么这个x在link的时候就是平铺唯一,其他模块如果也导出x,链接就会报错。foo.h
foo.c
as
DTU是symbol类型:
link:
gcc -o app foo.o main.o
如果我们不在foo.h中extern int bar;则在main.c中需要手动声明extern int bar
但这里
bar = 7
是编译不通过的,因为bar = 7是一个expression, 而不是definition。但是如果你写int bar = 7 则表示你在main模块中定义了一个全局变量bar,这样也冲突,所以两种都不行,只能在函数中去做expression。static local variables
运行后输出:
和全局变量的最大区别就是控制住了count的scope限定在run方法中。
static global variables (Multi-file variable scope example)
简单来说,static的全局变量的scope仅限于此模块,不允许外部链接。
static function
仅限于此模块进行调用,不允许外部模块使用。
所以默认应该用static,需要开放到才需要去掉static。
Structs
通过typedef 省略使用的时候需要struct。
参考阅读