字符串篇:
NSString与CString之间转换:
[NSstring UTF8String]方法就能够得到对应的c语言string的指针。所以用char*来接收返回值。
增强for
for (NSString * str in mArray) {
NSLog(@"固定数组 %@", str);
}
使用增强for的时刻,这里的Nsstring并不能够实现对条件的限制,即便数组内的对象不是NSString,也会被当做NSString类型来遍历出来。
关于Core Foundation框架:
Core Foundation框架和Foundation框架紧密相关,它们为相同功能提供接口,但Foundation框架提供Objective-C接口。如果您将Foundation对象和Core Foundation类型掺杂使用,则可利用两个框架之间的 “toll-free bridging”。所谓的Toll-free bridging是说您可以在某个框架的方法或函数同时使用Core Foundatio和Foundation 框架中的某些类型。很多数据类型支持这一特性,其中包括群体和字符串数据类型。每个框架的类和类型描述都会对某个对象是否为 toll-free bridged,应和什么对象桥接进行说明。
自 Xcode4.2 开始导入ARC机制后,为了支持对象间的转型,Apple又增加了许多转型用的关键字。这一讲我们就来了解其用法,以及产生的理由。
为了解决这一问题,我们使用 __bridge 关键字来实现id类型与void*类型的相互转换。看下面的例子。
- id obj = [[NSObject alloc] init];
- void *p = (__bridge void *)obj;
- id o = (__bridge id)p;
将Objective-C的对象类型用 __bridge 转换为 void* 类型和使用 __unsafe_unretained 关键字修饰的变量是一样的。被代入对象的所有者需要明确对象生命周期的管理,不要出现异常访问的问题。
除过 __bridge 以外,还有两个 __bridge 相关的类型转换关键字:
- __bridge_retained
- __bridge_transfer
接下来,我们将看看这两个关键字的区别。
__bridge_retained
先来看使用 __bridge_retained 关键字的例子程序:
- id obj = [[NSObject alloc] init];
- void *p = (__bridge_retained void *)obj;
从名字上我们应该能理解其意义:类型被转换时,其对象的所有权也将被变换后变量所持有。如果不是ARC代码,类似下面的实现:
- id obj = [[NSObject alloc] init];
- void *p = obj;
- [(id)p retain];
可以用一个实际的例子验证,对象所有权是否被持有。
- void *p = 0;
- {
- id obj = [[NSObject alloc] init];
- p = (__bridge_retained void *)obj;
- }
- NSLog(@"class=%@", [(__bridge id)p class]);
出了大括号的范围后,p 仍然指向一个有效的实体。说明他拥有该对象的所有权,该对象没有因为出其定义范围而被销毁。
相反,当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用 __bridge_transfer 关键字。文字有点绕口,我们还是来看一段代码吧。
如果ARC无效的时候,我们可能需要写下面的代码。
- // p 变量原先持有对象的所有权
- id obj = (id)p;
- [obj retain];
- [(id)p release];
那么ARC有效后,我们可以用下面的代码来替换:
- // p 变量原先持有对象的所有权
- id obj = (__bridge_transfer id)p;
可以看出来,__bridge_retained 是编译器替我们做了 retain 操作,而 __bridge_transfer 是替我们做了 release1。
事实上,为什么要存在桥bridge,就是因为在arc下,只能对oc对象进行处理,而对coreFoundation的指针却不能自动retain和release操作,所以,需要程序员在用到这些代码的时刻,手动的对这些类型对象进行引用计数的操作。