Pet*_* W. 6 xcode objective-c ios gpuimage swift
我正在尝试将应用程序从Objective-C移植到Swift,但我遇到了GPUImageFilter子类的问题.
在Obj-C中,继承GPUImageFilter并使用不同的片段着色器就像这样简单
- (id)init;
{
NSString *fragmentShaderPathname = [[NSBundle mainBundle] pathForResource:@"TestShader" ofType:@"fsh"];
NSString *fragmentShaderString = [NSString stringWithContentsOfFile:fragmentShaderPathname encoding:NSUTF8StringEncoding error:nil];
if (!(self = [super initWithFragmentShaderFromString:fragmentShaderString]))
{
return nil;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何在Swift中做到这一点.这是我的新初始化程序:
override init() {
let fragmentShaderPathname = NSBundle.mainBundle().pathForResource("TestShader", ofType: "fsh")!
let fragmentShaderString = NSString(contentsOfFile: fragmentShaderPathname, encoding: NSUTF8StringEncoding, error: nil)
super.init(fragmentShaderFromString: fragmentShaderString)
}
Run Code Online (Sandbox Code Playgroud)
一旦调用此应用程序,应用程序就会崩溃并显示以下错误消息:
/Users/peterwunder/Documents/XCode/welp/welp/GPUImageTestFilter.swift: 12: 7: fatal error: use of unimplemented initializer 'init(vertexShaderFromString:fragmentShaderFromString:)' for class 'welp.GPUImageTestFilter'
我究竟做错了什么?
有趣的问题!由于Swift和Objective-C之间的初始化不同,您将被绊倒.如果GPUImageFilter该类是用Swift编写的,那么编译器就不会让你进行这种设置,但是由于你是混合和匹配的,所以直到运行时才会抱怨.以下是您尝试实例化子类时发生的情况:
let myFilter = CustomGPUImageFilter()init()加载着色器字符串并调用super.init(fragmentShaderString: "foo")GPUImageFilter.init(fragmentShaderString:)电话[self initWithVertexShaderFromString:@"bar" fragmentShaderFromString:@"foo"].self最后一行是什么类型的?如果你从你的子类的初始化程序调用,那么它的类型self实际上是你的子类的类型:CustomGPUImageFilter.因此被调用的初始化程序实际上在您的子类上.为什么这是个问题?
不幸的是,如果Swift类定义了自己的指定初始化程序,它们就不会自动从它们的超类继承初始化程序init().因此,运行时尝试调用CustomGPUImageFilter.init(vertexShaderFromString:fragmentShaderFromString:),找不到它,并与该错误消息一起崩溃.
令人高兴的是,修复非常简单.如果将初始化程序标记为convenience init,则不再定义指定的初始化程序,这意味着您的子类将继承初始化程序GPUImageFilter.然后在上面的步骤3中,运行时将在您的子类上找到继承的初始化程序并执行而不会出现问题.请注意,您需要拨打电话self.init...而不是super.init...:
convenience override init() {
let fragmentShaderPathname = NSBundle.mainBundle().pathForResource("TestShader", ofType: "fsh")!
let fragmentShaderString = NSString(contentsOfFile: fragmentShaderPathname, encoding: NSUTF8StringEncoding, error: nil)
self.init(fragmentShaderFromString: fragmentShaderString)
}
Run Code Online (Sandbox Code Playgroud)
有关此过程的更多信息,请阅读Swift文档中有关类继承和初始化的部分.该过程与Objective-C 有很大不同.
| 归档时间: |
|
| 查看次数: |
783 次 |
| 最近记录: |