The iOS SpeakHere example code在类SpeakHereController
,stopRecord
和record
中有一对方法,分别保存和初始化文件以保存录制内容。这两种方法处理文件名字符串略有不同,正如您在这些方法中的以下两行代码中所看到的那样。
recordFilePath = (CFStringRef)[NSTemporaryDirectory() stringByAppendingPathComponent: @"recordedFile.caf"];
recorder->StartRecord(CFSTR("recordedFile.caf"));
字符串"recordedFile.caf"
出现一次前有@
符号,有一次没有。我打算使用以下NSString构造来生成filename
,但我不知道如何在本段提到的两个地方正确使用结果。所以我的问题是如何在这些行中使用构造的字符串filename
?
@property int counter;
NSString *filename = [[NSString alloc] initWithFormat:@"recordedFile%d.caf",self.counter];
答案 0 :(得分:1)
试
recorder->StartRecord(CFSTR([filename UTF8String]));
答案 1 :(得分:0)
区别在于字符串对象的C API(Core Foundation中的CFStringRef
)与字符串对象的Objective-C API(Cocoa中的NSString
)。
编译器知道@"..."
是一个Objective-C字符串文字,并构造一个({1}}的私有子类的静态实例。
编译器并不完全具有NSString
文字的类似原生知识。相反,Apple的头文件定义了CFString
预处理器宏,以将C风格的字符串包装在Core Foundation字符串中。传递给宏的参数必须是C字符串文字(例如CFSTR()
)。通过运行时表达式返回非文字C字符串指针的另一个答案中的语法不仅不正确,我不相信它可以编译。根据编译器,"foo"
可能会生成一个真正的编译时CFSTR()
对象,而不是运行时表达式。
所以:CFString
是一个@"recordedFile.caf"
字面值,NSString
是一个C字符串文字变为CFSTR("recordedFile.caf")
。您应该将其视为CFStringRef
字面值。
令人高兴的是,Apple设计了Core Foundation和Cocoa,以便CFString
和NSString
免费桥接。它们在某种抽象层次上是同一种对象。您可以自由地在两种类型之间进行类型转换。使用ARC,这种类型转换需要一个桥梁,让ARC知道更改的内存管理。
所以,你可以这样做:
CFString
或者:
CFStringRef cfstring = CFSTR("recordedFile.caf");
NSString* nsstring = (__bridge NSString*)cfstring;
针对您的具体情况:
NSString* nsstring = @"recordedFile.caf";
CFStringRef cfstring = (__bridge CFStringRef)nsstring;