gpt4 book ai didi

ios - 如果我想给自己分配一个属性怎么办?

转载 作者:IT王子 更新时间:2023-10-29 05:12:48 25 4
gpt4 key购买 nike

如果我尝试运行以下代码:

photographer = photographer

我得到错误:

Assigning a property to itself.


我想将属性分配给自身以强制运行 photographer didSet block 。

这是一个真实的例子:在 Winter 2013 Stanford iOS course 的“16. Segues and Text Fields”讲座中(13:20),教授推荐写类似下面的代码:

@IBOutlet weak var photographerLabel: UILabel!

var photographer: Photographer? {
didSet {
self.title = photographer.name
if isViewLoaded() { reload() }
}
}

override func viewDidLoad() {
super.viewDidLoad()
reload()
}

func reload() {
photographerLabel.text = photographer.name
}

注意:我做了以下改动:(1)代码从Objective-C切换到了Swift; (2) 因为在Swift中,我使用了属性的didSet block ,而不是setPhotographer:方法; (3) 而不是 self.view.window 我正在使用 isViewLoaded 因为前者错误地强制 View 在访问 view 属性时加载; (4) reload() 方法(仅)为了简单起见更新标签,因为它更像我的代码; (5) 添加了摄影师IBOutlet 标签以支持这种更简单的代码; (6) 由于我使用的是 Swift,isViewLoaded() 检查不再存在,仅仅是出于性能原因,现在 需要 来防止崩溃,因为 IBOutlet 是定义为 UILabel! 而不是 UILabel? 因此在加载 View 之前尝试访问它会使应用程序崩溃;这在 Objective-C 中不是强制性的,因为它使用空对象模式。

我们两次调用reload的原因是因为我们不知道该属性是在创建 View 之前还是之后设置的。例如,用户可能首先设置属性,然后呈现 View Controller ,或者他们可能呈现 View Controller ,然后更新属性。

我喜欢这个属性对于 View 何时加载是不可知的(最好不要对 View 加载时间做出任何假设),所以我想在我自己的代码中使用相同的模式(仅略微修改):

@IBOutlet weak var photographerLabel: UILabel?

var photographer: Photographer? {
didSet {
photographerLabel?.text = photographer.name
}
}

override func viewDidLoad() {
super.viewDidLoad()
photographer = photographer
}

这里不是创建一个从两个地方调用的新方法,我只想要 didSet block 中的代码。我希望 viewDidLoad 强制调用 didSet,所以我将属性分配给它自己。不过,Swift 不允许我这样做。如何强制调用 didSet

最佳答案

Swift 3.1 之前,您可以将属性 name 分配给自身:

name = (name)

但这现在给出了相同的错误:“将属性分配给自身”

还有许多其他方法可以解决这个问题,包括引入临时变量:

let temp = name
name = temp

这太有趣了,不能不分享。我相信社区可以想出更多的方法来做到这一点,越疯狂越好

class Test: NSObject {
var name: String? {
didSet {
print("It was set")
}
}

func testit() {
// name = (name) // No longer works with Swift 3.1 (bug SR-4464)
// (name) = name // No longer works with Swift 3.1
// (name) = (name) // No longer works with Swift 3.1
(name = name)
name = [name][0]
name = [name].last!
name = [name].first!
name = [1:name][1]!
name = name ?? nil
name = nil ?? name
name = name ?? name
name = {name}()
name = Optional(name)!
name = ImplicitlyUnwrappedOptional(name)
name = true ? name : name
name = false ? name : name
let temp = name; name = temp
name = name as Any as? String
name = (name,0).0
name = (0,name).1
setValue(name, forKey: "name") // requires class derive from NSObject
name = Unmanaged.passUnretained(self).takeUnretainedValue().name
name = unsafeBitCast(name, to: type(of: name))
name = unsafeDowncast(self, to: type(of: self)).name
perform(#selector(setter:name), with: name) // requires class derive from NSObject
name = (self as Test).name
unsafeBitCast(dlsym(dlopen("/usr/lib/libobjc.A.dylib",RTLD_NOW),"objc_msgSend"),to:(@convention(c)(Any?,Selector!,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject
unsafeBitCast(class_getMethodImplementation(type(of: self), #selector(setter:name)), to:(@convention(c)(Any?,Selector!,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject
unsafeBitCast(method(for: #selector(setter:name)),to:(@convention(c)(Any?,Selector,Any?)->Void).self)(self,#selector(setter:name),name) // requires class derive from NSObject
_ = UnsafeMutablePointer(&name)
_ = UnsafeMutableRawPointer(&name)
_ = UnsafeMutableBufferPointer(start: &name, count: 1)
withUnsafePointer(to: &name) { name = $0.pointee }

//Using NSInvocation, requires class derive from NSObject
let invocation : NSObject = unsafeBitCast(method_getImplementation(class_getClassMethod(NSClassFromString("NSInvocation"), NSSelectorFromString("invocationWithMethodSignature:"))),to:(@convention(c)(AnyClass?,Selector,Any?)->Any).self)(NSClassFromString("NSInvocation"),NSSelectorFromString("invocationWithMethodSignature:"),unsafeBitCast(method(for: NSSelectorFromString("methodSignatureForSelector:"))!,to:(@convention(c)(Any?,Selector,Selector)->Any).self)(self,NSSelectorFromString("methodSignatureForSelector:"),#selector(setter:name))) as! NSObject
unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setSelector:")),to:(@convention(c)(Any,Selector,Selector)->Void).self)(invocation,NSSelectorFromString("setSelector:"),#selector(setter:name))
var localVarName = name
withUnsafePointer(to: &localVarName) { unsafeBitCast(class_getMethodImplementation(NSClassFromString("NSInvocation"), NSSelectorFromString("setArgument:atIndex:")),to:(@convention(c)(Any,Selector,OpaquePointer,NSInteger)->Void).self)(invocation,NSSelectorFromString("setArgument:atIndex:"), OpaquePointer($0),2) }
invocation.perform(NSSelectorFromString("invokeWithTarget:"), with: self)
}
}

let test = Test()
test.testit()

关于ios - 如果我想给自己分配一个属性怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31930257/

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