// Objective-C NSObject* ptr = ...; // some pointer if ([ptr isKindOfClass:[foo class]] [ptr somefunction:5:3]; // C++ CPPObject* ptr = ...; // some pointer foo* f = dynamic_cast<foo*>(ptr); if (f) f->somefunction(5,3);
现在只有使用NSObject的"isKindOfClass"助手——所有Object-C类的基础,才能像在C++中那样向下转型.
符合协议?
// Objective-C NSObject* ptr = ...; // some pointer if ([ptr conformsToProtocol:@protocol(foo)] [ptr somefunction:5:3]; // C++ CPPObject* ptr = ...; // 某个也继承自foo的指针 foo* f = ptr; // 或者编译器会警告我们说ptr不能同foo兼容. f->somefunction(5,3);现在我们要检查接收器是否 符合一个协议 (或者说,在C++就是实现一个接口), 以便我们可以发送这个协议包含的消息. 嘿嘿,它像极了Java的类和接口,而在C++中,完全被实现的类和一个“接口”之间没有技术上的差别.
void* 、 id 或者 SEL?
// Objective-C id ptr = ...; // some pointer if ([ptr conformsToProtocol:@protocol(foo)] [ptr somefunction:5:3]; SEL s = @selector(foo:); // a pointer to a function foo that takes 1 parameter // C++ void* ptr = ...; // some pointer foo* f = dynamic_cast<foo*>(ptr); if (f) f->somefunction(5,3);id 是通用的用于Objective-C类的类似于 void* 的东西. 你只能使用id而不是 void* 因为id可以通过ARC(稍后会详细介绍到它)编程一个可被管理的指针,而因此编译器需要在元指针类型和Objective-C指针之间做出区分. SEL 是一个用于选择器(C++函数指针)的通用类型,而你一般可以通过使用关键字@selector带上函数名字和:::::s的一个数字来创建一个选择器, 这取决于可以传入多少参数. 选择器实际上就是一个字符串,它会在运行时绑定到一个方法识别器.
类定义,方法,数据,继承
// Objective C @class f2; // forward declaration @interface f1 : NSOBject // Objective-C supports only public and single inheritance { int test; // default = protected @public int a; int b; f2* f; } - (void) foo; @end @implementation f1 - (void) foo { a = 5; // ok self->a = 5; // ok super.foo(); // parent call } @end // C++ class f1 : public CPPObject { int test; // default = private public: class f2* f; // forward declaration int a; int b; void foo(); } void f1 :: foo() { a = 5; // ok this->a = 5; // ok CPPOBject::foo(); // parent call }Objective-C中的实现范围在@implementation/@end 标记 (在 C++ 中我们可以将实现放在任何带有::范围操作符的地方)之中. 它使用@class关键字用于事先声明. Objective-C 默认带有 私有(private) 保护, 但仅用于数据成员(方法必须是公共的). Objective-C 使用 self 而不是 this ,并且它还可以通过super关键字调用它的父类.
构造器和析构器
// Objective-C NSObject* s = [NSObject alloc] init]; // can return nil if construction failed [s retain]; // Increment the ref count // C++ CPPObject* ptr = new CPPObject(); // can throw ptr->AddRef(); // Objective-C NSObject* s = [NSObject alloc] initwitharg:4]; [s release]; // C++ CPPOBject* ptr = new CPPOBject(4); ptr->Release();Objective-C中的内存分配是通过静态成员方法alloc来实现的,所有 (做为NSObject后裔)的对象都有这个方法. self 在Objective-C中是可以被赋值的,而如果构建失败的话它就会设置成nil(而在C++中则会被抛出一个异常). 内存分配之后实际被构造器调用的是一个公共的成员函数,在Objective-C中默认的是init方法.
Objective-C 使用同COM益阳的引用计数方法, 而它也使用 retain 和 release (等同于IUnknown的 AddRef() 和 Release() 方法). 当引用计数到了0,则对象会从内存中被移除掉.
多线程
// Objective C @interface f1 : NSOBject // Objective-C supports only public and single inheritance { } - (void) foo; - (void) threadfunc :(NSInteger*) param; - (void) mt; @end @implementation f1 - (void) threadfunc : (NSInteger*) param { [self performSelectorOnMainThread: @selector(mt)]; } - (void) mt { } - (void) foo { [self performSelectorInBackground: @selector(thradfunc:) withObject:1 waitUntilDone:false]; <div></div>} @endObjective-C 有一些针对NSObject的内建功能,可以在另外一个线程中操作一个选择器 (== 调用一个成员), 在主线程中,等待一次调用等等 . 在NSObject 参见更多信息.
内存和ARC
// Objective-C @interface f1 : NSObject { } @property (weak) NSAnotherObject* f2; // 当没有其它强引用存在的时候,它将会被自动设置成. @end - (void) foo { NSObject* s = [NSObject alloc] init]; // 如果构造失败的话会返回nil // use s // end. Hooraah! Compiler will automatically call [s release] for us! }这里需要你忘记自己良好的 C++ 习惯. OK Objective-C 使用了一个垃圾收集机制,这种东西我们C++很讨厌,因为它很慢并会让我们想到Java. 但是 ARC (自动进行引用计算) 是一种 编译时间 特性,它会告诉编译器 "这里是我的对象:请帮我算算啥时候它们才要被销毁吧". 使用ARC你就不需要发送 retain/release 消息给你的对象了; 编译器会自动帮你代劳的.