2014-10-29 45 views
5
import Foundation 
import MobileCoreServices 

func checkFileExtension(fileName: NSString){ 
    println(fileName) 

    var fileExtension:CFStringRef = fileName.pathExtension 

    println(fileExtension) 

    var fileUTI:CFStringRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil) 

    println(fileUTI) 

    let testBool = UTTypeConformsTo(fileUTI, kUTTypeImage) != 0 

    if testBool{ 
     println("image") 
    } 
} 

我得到這個錯誤UTTypeCreatePreferredIdentifierForTag和CFStringRef斯威夫特

錯誤: '非託管' 是無法轉換爲 'CFStringRef'

在行

VAR fileUTI: CFStringRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,fileExtension,nil)

有什麼想法?由於

回答

15

UTTypeCreatePreferredIdentifierForTag傳回的Unmanaged<CFStringRef>,所以你需要獲得價值了Unmanaged對象,然後才能使用它:

var unmanagedFileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil) 
var fileUTI = unmanagedFileUTI.takeRetainedValue() 

需要注意的是我打電話,因爲UTTypeCreatePreferredIdentifierForTagtakeRetainedValue()將返回一個對象,我們負責釋放。在takeRetainedValue()評論說:

得到這個非託管的參考值作爲託管引用和 消耗它的一個不平衡的保留。

當函數返回一個非託管引用,並且你知道你負責釋放結果時,這很有用。

如果你得到一個Unmanaged對象從你確定你負責釋放該對象,其中一個功能回來了,叫takeUnretainedValue()代替。

+8

takeRetainedValue的VS takeUnretainedValue選擇僅依賴(我理解文檔)上的核心基礎功能是否返回(+1)保留的對象或不。 UTTypeCreatePreferredIdentifierForTag()在其名稱中有「Create」,所以根據返回一個(1)保留對象的內存管理規則,調用者必須最終釋放該對象。所以你必須在這裏調用takeRetainedValue,否則這個對象永遠不會被釋放,並且你有泄漏。 – 2014-10-29 16:34:48

+2

在https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html中比較「創建規則」。 – 2014-10-29 16:38:21

+0

感謝您的全面回答!真的幫助我! – pbeo 2014-10-29 16:39:12

0

我只想提一下我發佈的一個小模塊,它以更好的方式處理這類事情。你的榜樣將成爲:

import SwiftUTI 

func checkFileExtension(fileURL: URL){ 

    let uti = UTI(withExtension: fileURL.pathExtension) 

    if uti.conforms(to: .image) { 

     print("image") 
    } 
} 

這是可以在這裏找到:https://github.com/mkeiser/SwiftUTI