当我开始为iOS写代码的时候,我意识到,作为一个C++开发者,我必须花费更多的时间来弄清楚Objective-C中怪异的东西。这就是一个帮助C++专家的快速指南,能够使他们快速的掌握Apple的iOS语言。
请注意这绝不是一个完整的指南,但是它让你避免了阅读100页的手册。除此之外,我知道你喜欢我的写作风格。
Objective-C 和 Core Foundation 对象相互转换的内存管理总结
背景需要C++的技能,我会比较C++和Objective-C的东西。此外,COM编程也是有用的,因为Objective-C有类似于IUnkown的东西,因此基础的COM编程是有帮助的(但不是必须的)
Objective C++是C++和Objective C的组合。你也能使用任何C++的东西混合到Objective C中,但是记住重新命名你的文件从.m到.mm
铛 - 铛!我们马上就开始我们的教程. 首先我会介绍 Objective-C 的东西,然后是C++中与它对等的东西.
成员函数
// Objective-C
- (int) foo : (int) a : (char) b {}
+ (int) foo : (int) a : (char) b {}
// C++
int foo(int a,char b) {}
static int foo(int a,char b) {}
// Objective-C
- (void) foo2 val1:(int) a; // named argument
// call
[obj foo2 val1:5]; // merely helper: You remember that 5 is assigned to param name val1.
- 表示的是一个一般的成员函数(通过一个对象实体访问), 而 + 则表示一个静态成员函数, 不需要使用实体就能访问. 当然,像C++, 静态成员不能访问实体变量.
此外,Objective-C函数函数可以有赋予了名称的参数,这样让什么参数获得什么值会更一目了然. 理论上,被赋予了名称的参数允许程序员按任何顺序传入参数,但是Objective-C却规定要按声明的顺序传参.
通过一个指针或者一个静态成员调用一个成员
// Objective-C
NSObject* ptr = ...; // some pointer
[ptr foo:5:3]; // call foo member with arguments 5 and 3
[NSObject staticfoo:5:3]; // call static function of NSOBject with arguments 4 and 3
// C++
CPPObject* ptr = ...; // some pointer
ptr->foo(5,3);
CPPObject::staticfoo(5,3);
Objective-C 使用 [ ] 来调用成员函数并传入用:分割开的参数, 其对于ObjectiveC中ptr为nil的情况非常友好,在这种情况下“调用”将会被忽略掉(而在C++中,这种情况会抛出一个指针冲突异常 ). 这使得消除对nil对象的检查成为可能.
协议VS接口
// Objective-C
@protocol foo
- (void) somefunction;
@end
@interface c1 : NSObject<foo>
@end
@implementation c1
- (void) somefunction { ... }
@end
// C++
class foo
{
virtual void somefunction() = 0;
};
class c1 : public NSObject, public foo
{
void somefunction() { ... }
}
协议= 抽象类. Objective-C 和 C++ 之间的区别在于,在 Objective-C 中, 函数并不是必须要被实现的. 你可以让一个可选的方法被动的被声明,而这仅仅只是向编译器发出暗示而已,并不是编译必须的.
检查一个方法是否被实现了
// Objective-C
NSObject* ptr = ...; // some pointer
[ptr somefunction:5:3]; // NSObject 不必一定为其编译而实现somefunction. 如果没有被实现的话,会引发异常.
// C++
CPPObject* ptr = ...; // some pointer
ptr->somefunction(5,3); // CPPObject 必须实现 somefunction() 否则程序根本就不会被编译.
Objective-C 成员函数就是(Smalltalk中的) "消息" 而在Objective-C中时,我们则说接收者 (即指针) 会向一个选择器做出回应, 这意味着其实现了我们尝试去调用的虚函数. 当有一个接口是, C++ 对象必须实现其所有的成员函数. 而在 Objective-C 中这并不是必须的,因此我们可以向并不必须要实现它的某个地方发送一个”消息“ (如此就会引发一个异常).
// Objective-C
NSObject* ptr = ...; // some pointer
if ([ptr respondsToSelector:@selector(somefunction::)]
[ptr somefunction:5:3];
现在我们就可以确定接收者向选择器做出回应, 我们因此就可以调用它了. 在 C++ 中不需要这样的检查, 因为实现必须常常”向选择器做出回应“, 否则源代码根本就不会被编译. 请注意我们必须知道选择器获取了多少个参数(因此在该@selector中是2个 ::s