Error: Ambiguous reference to member 'subscript' in Swift 3

允我心安 提交于 2019-12-22 08:57:06

问题


I downloaded the Xcode 8 beta and converted my syntax to Swift 3. When I did, I got the eponymous error with this code (this didn't happen before):

Swift 3:

do {
    let fileAttributes = try FileManager.default().attributesOfItem(atPath: fileURL.path!) // Error here
    let fileSizeNumber = fileAttributes[NSFileSize] as! NSNumber
    fileSize = fileSizeNumber.longLongValue
} catch _ as NSError {
    print("Filesize reading failed")
}

Swift 2:

do {
    let fileAttributes = try NSFileManager.defaultManager().attributesOfItemAtPath(fileURL.path!)
    let fileSizeNumber = fileAttributes[NSFileSize] as! NSNumber
    fileSize = fileSizeNumber.longLongValue
} catch _ as NSError {
    print("Filesize reading failed")
}

Is this a bug in Swift 3, or am I missing something?

I know there are many questions about the same error, but those don't fix my problem. I'm happy to edit for clarification.

Thanks in advance!


回答1:


I think something like this should work:

do {
    let fileAttributes = try FileManager.default().attributesOfItem(atPath: file.path!)
    if let fileSizeNumber = fileAttributes["NSFileSize"] as? NSNumber {
        let fileSize = fileSizeNumber.int64Value

    }
} catch let error as NSError {
    print("Filesize reading failed: \(error.debugDescription)")
}

Since NSFileSize was just a constant string I've replaced it by its raw value. It seems ok - but it would be better to find the official equivalent, of course (which I didn't manage to for now, so don't take this solution for granted, it's just a workaround).

Update for Xcode 8 GM:

Using FileAttributeKey.size is better than using the hardcoded constant (thanks @rudy for the reminder). Here's an updated example:

do {
    let attributes = try FileManager.default.attributesOfItem(atPath: file.path)
    if let size = attributes[FileAttributeKey.size] as? NSNumber {
        let fileSize = size.int64Value
        print(fileSize)
    }
} catch {
    print(error.localizedDescription)
}



回答2:


This works in Swift 3:

var fileSize: UInt64 // size in bytes

do {
    let fileAttributes: NSDictionary? = try FileManager.default().attributesOfItem(atPath: fileURL.path!)
    if let fileSizeNumber = fileAttributes?.fileSize() { fileSize = fileSizeNumber }
} catch let error as NSError {
    print("Filesize reading failed: \(error.debugDescription)")
}

By casting the attributes into NSDictionary, many built-in methods become available including .fileSize():

  • .fileGroupOwnerAccountName()
  • .fileModificationDate()
  • .fileOwnerAccountName()
  • .filePosixPermissions()
  • .fileSize()
  • .fileSystemFileNumber()
  • .fileSystemNumber()
  • .fileType()

It's easy to discover their return data types by inspecting them with option-Click in Swift.




回答3:


This works on the Dictionary as returned from the call:

fileAttributes[FileAttributeKey.size.rawValue]

(Swift 3 as of XCode8 WWDC)



来源:https://stackoverflow.com/questions/37874157/error-ambiguous-reference-to-member-subscript-in-swift-3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!