0

iOS SpeakHere 示例代码在 Class 中有一对方法SpeakHereController,它们分别保存stopRecordrecord初始化一个用于保存录音的文件。这两种方法处理文件名字符串略有不同,您可以在这些方法中的以下两行代码中看到。

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];
4

2 回答 2

1

尝试

recorder->StartRecord(CFSTR([filename UTF8String]));
于 2014-08-13T01:34:06.147 回答
0

区别在于用于字符串对象的 C API(CFStringRef在 Core Foundation 中)与用于字符串对象的 Objective-C API(NSString在 Cocoa 中)。

编译器知道这@"..."是一个 Objective-C 字符串文字,并构造一个 (a private subclass of) 的静态实例NSString

编译器并不完全具有类似的CFString文字本机知识。相反,Apple 的标头定义了CFSTR()预处理器宏以将 C 风格的字符串包装在 Core Foundation 字符串中。传递给宏的参数必须是 C 字符串文字(例如"foo")。另一个答案中传递返回非文字 C 字符串指针的运行时表达式的语法不仅不正确,而且我不相信它可以编译。根据编译器,CFSTR()可能会产生一个真正的编译时CFString对象,而不是运行时表达式。

所以:@"recordedFile.caf"是一个NSString文字,CFSTR("recordedFile.caf")是一个 C 字符串文字变成了CFStringRef. 您应该将其视为CFString文字。

NSString令人高兴的是,Apple 设计了 ​​Core Foundation和Cocoa,以便CFString免费连接。在某种抽象层次上,它们是同一种对象。您可以自由地在两种类型之间进行类型转换。使用 ARC,这种类型转换需要一个让 ARC 了解更改的内存管理的桥梁。

所以,你可以这样做:

CFStringRef cfstring = CFSTR("recordedFile.caf");
NSString* nsstring = (__bridge NSString*)cfstring;

或者:

NSString* nsstring = @"recordedFile.caf";
CFStringRef cfstring = (__bridge CFStringRef)nsstring;

对于您的特定情况:

recorder->StartRecord((__bridge CFStringRef)filename);
于 2014-08-13T03:13:30.760 回答