类型 'MyWeights' 不符合协议 'NSCopying'
Type 'MyWeights' does not conform to protocol 'NSCopying'
我正在使用 Metal Performance Shader 设置神经网络,在编写权重初始化时遇到问题 class:类型 'MyWeights' 不符合协议 'NSCopying'。是什么导致了错误,以及如何解决这个问题?
PS。我试图通过添加 copy() 函数来修复它,但是我不知道 return 是什么或它是什么意思。
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
}
}
它确切地告诉你该做什么。
您需要声明您的class符合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
}
你必须实现整个 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
}
卷积数据源协议多年来发生了变化,最近添加了 NSCopying 协议,使得 MPSCNNConvolution 本身可以符合 NSCopying。一些示例代码可能没有继续进行。 MPS 应该检查可用的选择器,这样这就不是二进制兼容性问题,但是向前推进,您的协议采纳者应该符合 NSCopying 以便框架可以像宣传的那样运行。上面的答案演示了如何。
我正在使用 Metal Performance Shader 设置神经网络,在编写权重初始化时遇到问题 class:类型 'MyWeights' 不符合协议 'NSCopying'。是什么导致了错误,以及如何解决这个问题?
PS。我试图通过添加 copy() 函数来修复它,但是我不知道 return 是什么或它是什么意思。
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
}
}
它确切地告诉你该做什么。
您需要声明您的class符合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
}
你必须实现整个 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
}
卷积数据源协议多年来发生了变化,最近添加了 NSCopying 协议,使得 MPSCNNConvolution 本身可以符合 NSCopying。一些示例代码可能没有继续进行。 MPS 应该检查可用的选择器,这样这就不是二进制兼容性问题,但是向前推进,您的协议采纳者应该符合 NSCopying 以便框架可以像宣传的那样运行。上面的答案演示了如何。