好吧,这对我来说很奇怪,有人可以向我解释为什么handleDismiss
只能被称为一种方式吗?
请考虑以下内容:
import UIKit
class MenuLanucher: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
{
//[...] stuff
let menuItems: [MenuCellSetting] = {
return [
MenuCellSetting(name: "Exit Application", imageName: "hamburger", ontap: {
print("it is exit")
MenuLanucher.handleDismiss() //<-- 2. this is illegal: 'instance member 'handleDismiss' cannot be used on type 'MenuLanucher'; did you mean to use a value of this type instead?'
}),
MenuCellSetting(name: "Create", imageName: "gear", ontap: {
print("it is job")
self?.HandleDismiss() //<-- 2. illegal : 'Cannot use optional chaining on non-optional value of type '(MenuLanucher) -> () -> (MenuLanucher)''
}),
MenuCellSetting(name: "Cancel", imageName: "gear", ontap: {
print("it is nothing")
perform(#selector(MenuLanucher.handleDismiss)) //<-- 3. crashes on run time 'unrecognized selector sent to class'
})
]
}()
//[...] yet
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
menuItems[indexPath.item].ontap()
handleDismiss() //<--1. works
}
@objc func handleDismiss(){
print("dismiss works")
}
}
class MenuCellSetting: NSObject {
let name: String
let imageName: String
let ontap: ()->Void
init(name: String, imageName: String, ontap: @escaping ()->Void){
self.name = name
self.imageName = imageName
self.ontap = ontap
}
}
在此示例中
我的问题是:为什么有区别?发生了什么事?
编辑:self.?handleDismiss()也失败(参见图片)
答案 0 :(得分:2)
替换
let menuItems: [MenuCellSetting] = {
...
}()
使用
lazy var menuItems: [MenuCellSetting] = {
...
}()
问题在于实例常量在self
甚至还没有可用之前就已初始化,因此闭包中的self
实际上意味着与您期望的不同。 lazy var
是在首次调用时分配的,即在self
初始化之后,它们可以安全地访问self
。
实际上,为防止内存泄漏,您还必须使用[weak self]
:
MenuCellSetting(name: "Create", imageName: "gear", ontap: { [weak self] in
self?.HandleDismiss()
})
答案 1 :(得分:-1)
由于“ handleDismiss”不是类方法,因此无法通过类名称访问它。我们需要首先创建一个对象,然后可以通过点运算符访问它。请在类名前面添加括号以访问“ handleDismiss”方法。
此外,由于“ handleDismiss”方法位于同一类中,因此您不必提供类名。您可以直接调用方法名称。您可能必须使用self,因为调用处于关闭状态。
let menuItems: [MenuCellSetting] = {
return [
MenuCellSetting(name: "Exit Application", imageName: "hamburger", ontap: {
print("it is exit")
self.handleDismiss() //<-- 2. this is illegal: 'instance member 'handleDismiss' cannot be used on type 'MenuLanucher'; did you mean to use a value of this type instead?'
}),
MenuCellSetting(name: "Create", imageName: "gear", ontap: {
print("it is job")
}),
MenuCellSetting(name: "Cancel", imageName: "gear", ontap: {
print("it is nothing")
perform(#selector(self.handleDismiss)) //<-- 3. crashes on run time 'unrecognized selector sent to class'
})
]
}()
答案 2 :(得分:-1)
首先handleDismiss
不是类函数,因此您需要有一个类对象才能调用handleDismiss()
。
第二,您不应该只是在menuItems
中创建一个新对象,否则将在此新对象上调用此方法,并且不会对当前对象产生任何影响。
示例代码
struct MenuCellSetting {
var name: String
var imageName: String
var ontap: () -> ()
init(name: String, imageName: String, ontap: @escaping (() -> ())) {
self.name = name
self.imageName = imageName
self.ontap = ontap
}
}
class MenuLauncher {
let menuItems: [MenuCellSetting] = {
return [
MenuCellSetting(name: "Exit Application", imageName: "hamburger", ontap: { [weak self] in // Want to make sure that you only capture weak reference, otherwise it will create a memory-leak due to cyclic reference
print("it is exit")
self?.handleDismiss()
}),
MenuCellSetting(name: "Create", imageName: "gear", ontap: {
print("it is job")
}),
MenuCellSetting(name: "Cancel", imageName: "gear", ontap: { [weak self] in
print("it is nothing")
self?.handleDismiss()
})
]
}()
func handleDismiss() {
print("Dismissing")
}
}