CMBlockBuffer,在斯威夫特

问题描述:

我试图转换在这里的苹果公司的代码示例之一提供一些Objective C的代码UnsafeMutablePointer等:https://developer.apple.com/library/mac/samplecode/avsubtitleswriterOSX/Listings/avsubtitleswriter_SubtitlesTextReader_m.htmlCMBlockBuffer,在斯威夫特

结果我想出迄今如下:

func copySampleBuffer() -> CMSampleBuffer? { 

    var textLength : Int = 0 
    var sampleSize : Int = 0 

    if (text != nil) { 
     textLength = text!.characters.count 
     sampleSize = text!.lengthOfBytesUsingEncoding(NSUTF16StringEncoding) 
    } 

    var sampleData = [UInt8]() 

    // Append text length 
    sampleData.append(UInt16(textLength).hiByte()) 
    sampleData.append(UInt16(textLength).loByte()) 

    // Append the text 
    for char in (text?.utf16)! { 
     sampleData.append(char.bigEndian.hiByte()) 
     sampleData.append(char.bigEndian.loByte()) 
    } 

    if (self.forced) { 
     // TODO 
    } 

    let samplePtr = UnsafeMutablePointer<[UInt8]>.alloc(1) 
    samplePtr.memory = sampleData 

    var sampleTiming = CMSampleTimingInfo() 
    sampleTiming.duration = self.timeRange.duration; 
    sampleTiming.presentationTimeStamp = self.timeRange.start; 
    sampleTiming.decodeTimeStamp = kCMTimeInvalid; 

    let formatDescription = copyFormatDescription() 

    let dataBufferUMP = UnsafeMutablePointer<Optional<CMBlockBuffer>>.alloc(1) 

    CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault, samplePtr, sampleSize, kCFAllocatorMalloc, nil, 0, sampleSize, 0, dataBufferUMP); 

    let sampleBufferUMP = UnsafeMutablePointer<Optional<CMSampleBuffer>>.alloc(1) 

    CMSampleBufferCreate(kCFAllocatorDefault, dataBufferUMP.memory, true, nil, nil, formatDescription, 1, 1, &sampleTiming, 1, &sampleSize, sampleBufferUMP); 

    let sampleBuffer = sampleBufferUMP.memory 

    sampleBufferUMP.destroy() 
    sampleBufferUMP.dealloc(1) 

    dataBufferUMP.destroy() 
    dataBufferUMP.dealloc(1) 

    samplePtr.destroy() 
    //Crash if I call dealloc here 
    //Error is: error for object 0x10071e400: pointer being freed was not allocated 
    //samplePtr.dealloc(1) 

    return sampleBuffer; 
} 

我想尽量避免使用“不安全*”类型,尽管我不确定这是否可能。我也研究过使用一个结构体,然后以某种方式看待它,但我看到的例子似乎是基于sizeof的,它使用了定义的大小,而不是结构的当前大小。这将是我会使用以下结构:

struct SubtitleAtom { 
    var length : UInt16 
    var text : [UInt16] 
    var forced : Bool? 
} 

上用于该功能最适合夫特2代码任何建议,将不胜感激。

所以,首先,你的代码使用这种模式

class C { deinit { print("I got deinit'd!") } } 
struct S { var objectRef:AnyObject? } 

func foo() { 
    let ptr = UnsafeMutablePointer<S>.alloc(1) 
    let o = C() 
    let fancy = S(objectRef: o) 
    ptr.memory = fancy 
    ptr.destroy() //deinit runs here! 
    ptr.dealloc(1) //don't leak memory 
} 
// soon or later this code should crash :-) 
(1..<1000).forEach{ i in 
    foo() 
    print(i) 
} 

尝试在一个游乐场,并最有可能:-)崩溃。它出什么问题了?麻烦的是你的不平衡保留/释放周期。如何以安全的方式编写相同的文件?你删除了dealloc部分。但试着在我的代码片段中看到结果。代码再次崩溃:-)。比较安全的方法是正确初始化和去ininitialize(破坏)底层PTR的内存,你可以在接下来的片段看到

class C { deinit { print("I got deinit'd!") } } 
struct S { var objectRef:AnyObject? } 

func foo() { 
    let ptr = UnsafeMutablePointer<S>.alloc(1) 
    let o = C() 
    let fancy = S(objectRef: o) 
    ptr.initialize(fancy) 
    ptr.destroy() 
    ptr.dealloc(1) 
} 

(1..<1000).forEach{ i in 
    foo() 
    print(i) 
} 

现在按预期执行代码和所有保留/释放周期是平衡

+0

谢谢。只是为了清楚分配意味着类型的实例的数量,数据的大小或其他东西?文档并不完全清楚,所有示例始终提供“1”作为价值。 –

+1

@AndreM个实例 – user3441734