数组 2 | NSArray* a1 = [NSArray alloc] initWithObjects: @ "hello" ,@ "there" ,nil]; |
3 | NSString* first = [a1 objectAtIndex: 0 ]; |
NSArray和NSMutableArray是在Objective-C中处理数组的 两个类(两者的差异是,NSArray元素构造时必须通过构造函数,而NSMutableArray可以在之后更改)。典型构造函数的生效,你必须通过nil去作为“结尾元素”。排序/搜索/插入函数对于NSArray和NSMutableArray来说是一样的,在第一行中的例子它返回一个新的NSArray,而在NSMutableArray的例子里,它修改的是一个存在的对象。 分类 02 | class MyString : public string |
05 | void printmystring() { printf( "%s" ,c_str()); } |
10 | @interface MyString (NSString) |
11 | - ( void ) printmystring; |
14 | @implementation MyString (NSString) |
28 | NSString* s2 = @ "hello" ; |
C++依赖 继承机制来实现一个已知的类。这是很麻烦的,因为所有用户的实现类必须使用另外的类型名称(在例子中,MyString用来代替string)。Object-C通过使用 分类(Categories)允许扩展一个已知的类内 同型(same type)。上面链接中所有源代码在extension.h文件 (具有代表性的是像NSString+MyString.h这样的)中可以查看,上面例子中,我们立即就有可以调用新的成员函数,而不需要改变NSString类型为MyString。
块 和 Lambda 3 | -( void )addButtonWithTitle:(NSString*)title block:( void (^)(AlertView*, NSInteger))block; |
6 | [object addButtonWithTitle:@ "hello" block:[^(AlertView* a, NSInteger i){ }]; |
块 是Objective-C 用来模拟lambda功能的一种方式. 查看Apple的文档,从AlertView的示例 (使用块的UIAlertView)可以获得更多有关块的技术. C++ 开发者使用 Objective-C 和 ARC 的重要提示 你已经知道给所有的顾客都打两折对你而言有多痛苦了,因为你bug重重的软件会在发布模式下奔溃,而在调试模式下总是妥妥的. 没有用户会理解程序员,是不是? 让我们来看看这里发生了什么. s = 0 这一行将 0 赋值给了一个变量,而因此不管这个变量之前取值是什么,首先都会被释放掉,所以编译器在赋值之前执行了一次 [s release] . 如果 s 之前已经是 0 了,假设是在调试构建的话,不会发生任何不好的事情; 如果 s 是一个nil的话,使用[s release] 是再好也不过的. 然而,在发布模式下, s可能是一个野指针,所以它可能在被“初始化”为0之前包含任何值(这很危险是不是?).
在C++中,这并不是一个问题,因为它里面是不存在ARC的. 而在Objective-C中编译器并没有办法了解这是一次"赋值" 还是一次 "初始化" (如果是后者,它就不会发送发布消息). 下面是正确的方式:
现在编译器就不会去尝试调用一个 [s release] 因为它知道它是这个对象的第一次初始化. 请小心!
从Objective-C 对象到 C++ 类型的转换 3 | void * b = (__bridge void *)a; |
4 | void * c = (__bridge_retained void *)a; |
5 | NSObject* d = (__bridge_transfer NSObject*)c; |
我可以分析这一切,而我的建议是简单的. 不要 将ARC类型和非ARC类型混在一起. 如果你必须转换一些Objective-C对象的话,使用id而不是void*. 否则,你将会遇到严重的内存故障.
Objective-C 有而 C++ 没有的 C++ 有而 Objective-C 没有的阅读更多 从C++ 到 Objective-C 指南, 这里.历史记录
本文地址:http://www.oschina.net/translate/from-cplusplus-to-objective-c-a-quick-guide |