首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在CAGradientLayer上快速不调用类init方法

在CAGradientLayer上快速不调用类init方法
EN

Stack Overflow用户
提问于 2020-02-21 17:52:52
回答 1查看 154关注 0票数 3

我有一个目标-C子类'CAGradientLayer‘,它覆盖'+ (CAGradientLayer *)层’初始化器。它正确地包含在我的Bridging-Header中。

代码语言:javascript
复制
#import "ONCGradientLayer.h"

@implementation ONCGradientLayer

+ (ONCGradientLayer *)gradientLayer {
    return [ONCGradientLayer layer];
}

+ (ONCGradientLayer *)layer {
    ONCGradientLayer * layer = [super layer];
    layer.colors = @[(id)[[UIColor colorWithWhite:0.0 alpha:1] CGColor], (id)[[UIColor colorWithWhite:0.1 alpha:1] CGColor]];
    layer.startPoint = CGPointMake(0, 0);
    layer.endPoint = CGPointMake(0, 1);
    return layer;
}

通过调用[ONCGradientLayer layer][ONCGradientLayer gradientLayer],这一切都按照目标C的预期工作。

当我试图从init调用它时,会给我一个编译器警告,这个方法已经被重命名为ONCGradientLayer(),所以我必须调用ONCGradientLayer(),但是它不起作用,并且重写的初始化程序永远不会被调用。

我可以通过添加一个不同名称的初始化器来解决这个问题:

代码语言:javascript
复制
+ (ONCGradientLayer *)swiftInit {
    return [ONCGradientLayer layer];
}

我可以在快速使用ONCGradientLayer.swiftInit()中成功地调用它

是什么原因阻止我调用ONCGradientLayer()并获得重写的初始化程序?

更新:我可以通过重构ONCGradientLayer()来使用init方法,尽管我仍然很好奇为什么另一种方法不能工作。

代码语言:javascript
复制
- (instancetype)init {
    if (self = [super init]) {
        self.colors = @[(id)[DEFAULT_BACKGROUND_COLOR CGColor], (id)[[UIColor colorWithWhite:.1 alpha:1] CGColor]];
        self.startPoint = CGPointMake(0, 0);
        self.endPoint = CGPointMake(0, 1);
    }
    return self;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-22 05:18:58

这都是关于一个名为的Swift组件,它负责将Objective方法名称转换为Swift方法名称(反之亦然)。

Clang导入器假设,如果一个目标C类的类方法与类的名称相同,除了前缀和低胁迫(可能由with扩展)之外,它就是一个类工厂方法。

它还假设类工厂方法与其名称以相同方式构造的初始化器有效地相同,并且完全隐藏了相应的工厂方法,因为用ARC,两者之间没有意义的区别。

示例: NSString有工厂方法stringWithFormat:和初始化器initWithFormat:

好的,string和NSString一样,去掉了前缀和小写;所以Clang导入程序假设stringWithFormat:是工厂方法。此外,它的构造类似于initWithFormat:,因此Clang导入程序假定它们实际上是相同的,并隐藏了前者。

因此,您必须在Swift中说String(format:),意思是String.init(format:)。Clang进口商也剥离了with,但这是另一个故事。在Swift中没有String.withFormat(_:) (或类似的),匹配的目标-C stringWithFormat:

这正是ONCGradientLayer和gradientLayer的情况。类方法遵循类工厂方法命名约定。因此,感谢Clang导入器,如果存在一个init --并且存在--那么类工厂方法是隐藏的。因此,您必须调用init,在Swift中使用ONCGradientLayer()

但是您并没有定义init来返回修改后的ONCGradientLayer,因此结果是一个不需要修改的普通层。

如果你不喜欢,你有两个选择。你已经发现了他们是什么!

  • 将类工厂名称更改为makeGradientLayer。(这正是您通过提供名称swiftInit.)

所做的事情

  • ,或者,定义init以返回以与在layer中相同的方式修改的ONCGradientLayer。(你也是这么做的)
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60343945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档