【问题标题】:Type 'MyWeights' does not conform to protocol 'NSCopying'类型“MyWeights”不符合协议“NSCopying”
【发布时间】:2018-09-14 02:26:00
【问题描述】:

我正在使用 Metal Performance Shader 设置神经网络,在编写权重初始化类时遇到问题:Type 'MyWeights' does not conform to protocol 'NSCopying'。是什么导致了错误,以及如何解决这个问题?

PS。我试图通过添加 copy() 函数来修复它,但是我不知道返回什么或它意味着什么。

import Foundation
import MetalPerformanceShaders

class MyWeights: NSObject, MPSCNNConvolutionDataSource {
//Error: Type 'MyWeights' does not conform to protocol 'NSCopying'

/*
func copy(with zone: NSZone? = nil) -> Any {
    return self
}
*/

let name: String
let kernelWidth: Int
let kernelHeight: Int
let inputFeatureChannels: Int
let outputFeatureChannels: Int

var data: Data?

init(name: String, kernelWidth: Int, kernelHeight: Int,
     inputFeatureChannels: Int, outputFeatureChannels: Int,
     useLeaky: Bool = true) {
    self.name = name
    self.kernelWidth = kernelWidth
    self.kernelHeight = kernelHeight
    self.inputFeatureChannels = inputFeatureChannels
    self.outputFeatureChannels = outputFeatureChannels
}

func dataType() -> MPSDataType {
    return .float32
}

func descriptor() -> MPSCNNConvolutionDescriptor {
    let desc = MPSCNNConvolutionDescriptor(kernelWidth: kernelWidth,
                                           kernelHeight: kernelHeight,
                                           inputFeatureChannels: inputFeatureChannels,
                                           outputFeatureChannels: outputFeatureChannels)
    return desc
}

func weights() -> UnsafeMutableRawPointer {
    return UnsafeMutableRawPointer(mutating: (data! as NSData).bytes)
}

func biasTerms() -> UnsafeMutablePointer<Float>? {
    return nil
}

func load() -> Bool {
    if let url = Bundle.main.url(forResource: name, withExtension: "dat") {
        do {
            data = try Data(contentsOf: url)
            return true
        } catch {
            print("Error: could not load \(url): \(error)")
        }
    }
    return false
}

func purge() {
    data = nil
}

func label() -> String? {
    return name
}

}

【问题讨论】:

    标签: ios swift nsobject swift-protocols metal-performance-shaders


    【解决方案1】:

    准确地告诉你该做什么。

    您需要声明您的类符合NSCopying 协议,然后您需要实现该协议中唯一的函数copy(with:)

    class MyWeights: NSObject, MPSCNNConvolutionDataSource, NSCopying {
    
        func copy(with zone: NSZone? = nil) -> Any {
            return MyWeights(
              name: self.name,
              kernelWidth: self.kernelWidth,
              kernelHeight: self.kernelHeight,
              inputFeatureChannels: self.inputFeatureChannels,
              outputFeatureChannels: self.outputFeatureChannels,
              useLeaky: self.useLeaky)
        }
        //The rest of your class
    }
    

    【讨论】:

    • 在目标 C 中,你会丢失 -(nonnull instancetype) copyWithZone: (NSZone * __nullable) zone
    【解决方案2】:

    你必须实现整个 NSCopying 协议

    class MyWeights: NSObject, MPSCNNConvolutionDataSource, NSCopying {
    
        init(/* ... */) {
        // your init...
    
            super.init() // NSObject init
        }
    
        // add this method
        func copy(with zone: NSZone? = nil) -> Any {
            return super.copy() // NSObject copy
        }
        //The rest of your class
    }
    

    【讨论】:

      【解决方案3】:

      卷积数据源协议多年来发生了变化,最近添加了 NSCopying 协议,以便 MPSCNNConvolution 本身可以符合 NSCopying。一些示例代码可能没有向前推进。 MPS 应该检查可用的选择器,以便这不是二进制兼容性问题,但是向前看,您的协议采用者应该符合 NSCopying 以便框架可以像宣传的那样运行。上面的答案说明了如何。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-23
        • 2023-03-24
        • 1970-01-01
        相关资源
        最近更新 更多