gpt4 book ai didi

ios - 在基类或扩展 Swift 的静态方法中获取派生类型的类型名称

转载 作者:可可西里 更新时间:2023-11-01 01:49:40 25 4
gpt4 key购买 nike

长话短说将其粘贴到 Swift playground 中:

import UIKit

public protocol NibLoadable {
static var nibName: String { get }
}

extension NibLoadable where Self: UIView {
public static var nibName: String {
return String(describing: self)
}

func printName(){
print(Self.nibName)
}
}

public class Shoes: UIView, NibLoadable {


required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
printName()
}

override init(frame: CGRect) {
super.init(frame: frame)
printName()
}
}

public class Cake: Shoes {

}

let cake = Cake() // this line prints 'Shoes'

如何让它打印Cake,而不是Shoes

完整解释:

我找到了将 xib 文件加载到 Storyboard中的方法,如下所示: https://stackoverflow.com/a/47295926/2057955

这非常有效,但是我必须像这样将样板 NibLoadable 代码放入每个 View 中:

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupFromNib()
}

override init(frame: CGRect) {
super.init(frame: frame)
setupFromNib()
}

当您以这种方式获得 20-30 次观看时,这显然很烦人。

所以我正在尝试设置一个基类来处理这个问题,然后让所有东西都继承它。

不幸的是,无论我尝试了什么,String(describing: Self.self) 总是返回我的基类的名称,而不是派生类的名称。

当我在 XCode 中打开 Storyboard 时,我在控制台日志中收到此异常:

[MT] IBSceneUpdate: [scene update, delegate=] Error Domain=IBMessageChannelErrorDomain Code=3 "Failed to communicate with helper tool" UserInfo={NSLocalizedFailureReason=The agent raised a "NSInternalInconsistencyException" exception: Could not load NIB in bundle: 'NSBundle (loaded)' with name 'BaseNibLoadable.Type', IBMessageSendChannelException=Could not load NIB in bundle: 'NSBundle (loaded)' with name 'BaseNibLoadable.Type', NSLocalizedDescription=Failed to communicate with helper tool}

例子:

@IBDesignable
class BaseNibLoadable: UIView, NibLoadable {
// MARK: - NibLoadable
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupFromNib()
}

override init(frame: CGRect) {
super.init(frame: frame)
setupFromNib()
}
}
@IBDesignable
class SomeHeader: BaseNibLoadable {

@IBOutlet fileprivate weak var headerLabel: UILabel!
@IBInspectable var header: String? {
didSet {
self.headerLabel.text = header
}
}
}

显然,我的主包(两者的包相同)包含 SomeHeader.xib 文件。

所以我正在寻找的是以某种方式获取在 nibName 静态方法中实例化的实际类型的名称。

更新根据要求,这是我在问题顶部链接的原始答案(更确切地说,只是它的代码,否则它很长......请点击链接):

public protocol NibLoadable {
static var nibName: String { get }
}

public extension NibLoadable where Self: UIView {

public static var nibName: String {
return String(describing: Self.self) // defaults to the name of the class implementing this protocol.
}

public static var nib: UINib {
let bundle = Bundle(for: Self.self)
return UINib(nibName: Self.nibName, bundle: bundle)
}

func setupFromNib() {
guard let view = Self.nib.instantiate(withOwner: self, options: nil).first as? UIView else { fatalError("Error loading \(self) from nib") }
addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
view.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
view.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
view.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
view.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
}
}

更新 2

我确实知道子类此时肯定在堆栈中,因为如果我记录 Thread.callStackSymbols,实际的具体 View 类名称就在那里。

最佳答案

How do i make it print Cake, not Shoes?

改变

print(Self.nibName)

print(type(of:self).nibName)

关于ios - 在基类或扩展 Swift 的静态方法中获取派生类型的类型名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55464958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com