- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
作为maddy在下面的评论中提到,很明显你需要一个对象的引用才能调用它的方法。这可能实际上是我的问题:您如何跟踪实现协议(protocol)的所有对象?
回顾 Objective-C,我考虑过使用类似于 +load
或 +initialize
方法的东西,并将对象添加为特定 NSNotification 的观察者
。但这行不通,因为这些方法是类方法而不是实例方法。
所以,试着更具体一点:是否有一种方法可以在创建所有对象后调用它们?一种允许我将该对象添加到我管理的集合或作为特定 NSNotification
的观察者的方法?
P.S:我没有尝试为问题添加太多细节,因为我不想用我的糟糕、无意义的想法“污染”你。
所以...想象一下这段代码:
protocol MyProtocol: class {
func myMethod()
}
public class MyClass: MyProtocol {
func myMethod() {
print("myMethod called on MyClass")
}
}
extension UIView: MyProtocol {
func myMethod() {
print("myMethod called on UIView")
}
}
let myObject = MyClass()
let myView = UIView()
现在...我正在尝试找出一种方法,从不了解它们的第三个对象对这两个对象调用 myMethod
- 这是第三个对象的简化示例:
class MyManager {
func callMyMethodOnAllObjecs() {
// Do something here so that ALL objects present in memory that conform to MyProtocol get their myMethod called
}
}
有人吗?
最佳答案
请注意,您需要的功能属于动态类型语言,这意味着使用 Objective-C 运行时。这不会带来很多技术挑战,但会限制您可以使用的 Swift 实体的范围 - 基本上只有 NSObject
派生类。
简单地说,这是您需要的:
MyManager
中支持注册新创建的对象MyManager
的 MyProtocol
实例执行MyManager
中注册一个对象会带来管理器无限期保留该对象的风险。您可以在下面找到解决问题的代码:
// Since we need ObjectiveC specific runtime features, we need to
// restrict the protocol to the NSObject protocol
protocol MyProtocol: NSObjectProtocol {
func myMethod()
}
public class MyClass: NSObject, MyProtocol {
func myMethod() {
print("myMethod called on MyClass")
}
}
extension UIView: MyProtocol {
func myMethod() {
print("myMethod called on UIView")
}
}
extension NSObject {
// this is an alternative to the original init method, that besides the
// original edit it registers the object within MyManager
@objc func swizzledInit() -> NSObject {
// this is not recursive, as init() in exchanged with swizzledInit()
let `self` = swizzledInit()
if let `self` = self as? MyProtocol {
// the object is MyProtocol
MyManager.shared.register(self)
}
return self
}
}
class MyManager {
static let shared = MyManager()
private var objecters = [() -> MyProtocol?]()
private init() {
// let's swizzle init() with our custom init
if let m1 = class_getInstanceMethod(NSObject.self, #selector(NSObject.init)),
let m2 = class_getInstanceMethod(NSObject.self, #selector(NSObject.swizzledInit)) {
method_exchangeImplementations(m1, m2)
}
}
public func register(_ object: MyProtocol) {
// registering a block in order to be able to keep a weak reference to
// the registered object
objecters.append({ [weak object] in return object })
}
func callMyMethodOnAllObjecs() {
var newList = [() -> MyProtocol?]()
// go through the list of registered blocks, execute the method,
// and retain only the ones for wich the object is still alive
for object in objecters {
if let o = object() {
newList.append(object)
o.myMethod()
}
}
objecters = newList
}
}
// This is to make sure the manager is instantiated first,
// and thus it swizzles the NSObject initializer
_ = MyManager.shared
let myObject = MyClass()
let myView = UIView()
// an instance of MyClass and one of UIView will print stuff
MyManager.shared.callMyMethodOnAllObjecs()
综上所述,上面的代码:
NSObject
的 init
,这样除了原始的 init
之外,它还会将对象注册到您的管理器。callMyMethodOnAllObjecs
时清除其对象被释放的闭包。关于ios - 对符合协议(protocol)的所有对象调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41048058/
我们如何让 SwiftUI 对象,尤其是 Image,符合 Hashable 协议(protocol)? 我知道它们符合 Equatable 协议(protocol),所以主要问题是如何获取哈希值,或
我遇到了一些符合 AVAudioPlayerDelegate 的奇怪问题。以下正是我在一个全新的 Xcode 项目中所拥有的: import UIKit import AVFoundation cla
我一辈子都弄不明白为什么我会收到此类不符合 NSCoding 协议(protocol)的错误。也许另一双眼睛会有所帮助。我试图添加注释以明确每个函数在做什么。 import Foundation im
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
所有现代浏览器都理解 HTML,所以除了在键盘最右侧编写更多字符之外,兼容 XHTML 的意义何在。 最佳答案 没有一点我能想到的。 W3C 已经取消了 XHTML 2.0,尽管应该有一个 XHTML
我正在设计一个订单系统,状态设计模式似乎很合适,因为订单可以更改其状态,从而更改订单允许的功能。下面是我的基本类图: 我不喜欢这种方法,因为客户端无法查看某个方法是否受支持并且违反了里氏原则。我在下面
我正在考虑使用图形数据库来存储 IFC数据。理想情况下,数据库应该提供一种方法来定义 IFC 架构中定义的所有规则类型。但是,我不认为有任何这样的数据库,因为 IFC 中的某些规则类型非常复杂并且需要
我所在的组织必须满足 FISMA 对启用 FIPS 的系统的要求。我正在尝试做的一件事是为我们的密码实现哈希算法。我对此有很多选择:SHA-2、MD5、bcrypt(使用 Blowfish)、RIPE
我正在尝试实现我的自定义 CoreData Carpark 实体以符合 MKAnnotation,就像我们如何使 class 对象符合 >MKAnnotation. 我根据以下帖子调整了我的实现:th
我在 project-Swift.h 文件中收到名为“CBCentralManagerDelegate”的 No 类型或协议(protocol)。不知道我在这里哪里出错了。我认为这与 swift.h
我正在尝试读取之前写入 NVM 闪存的变量的值。 我的代码是: uintptr_t address = getAddress(); //[MISRA C++ Rule 5-2-8] cast from
所以我有这个练习要解决。我必须创建第一个。一个名为 Printable 的接口(interface),它有一个 put() 方法,该方法将接受实现 Comparable 的对象。 完成 interfa
我的问题涉及 IEEE 754 单精度数字。假设我有一个结构: typedef struct __ieee754 { int sign; int exponent; int mant
我需要使用 map,键为 uint32_t,值为 Meshes。我希望将网格布局在连续的内存中以 boost 性能,因为它们将经常被连续访问。 我想知道有哪些内存分配器库可以提供以下内容; 分配给连续
在处理小对象时,有哪些分配器可用于 STL。我已经尝试过使用 Boost 的池分配器,但没有得到任何性能提升(实际上,在某些情况下性能下降相当大)。 最佳答案 你没有说你使用的是什么编译器,但它可能带
我想做什么 我有一种划分事物的方法。此方法不会对数组进行完全排序;它只是简单地对数组进行分区,以便一侧的所有元素(某些预先确定的“中心”或“中点值”——但它不必导致均匀拆分)小于“中心”和另一侧的所有
假设我需要开发一个 REST 银行应用程序允许创建/销毁银行账户以及对帐户进行以下操作:withdraw/credit/getBalance。 创建帐户 PUT/银行/约翰 这里我使用 PUT 而不是
假设我有一个 struct 符合我的模型的 Equatable,如下所示: struct Model: Equatable { var a: Int = 0 var b: String
我目前正在研究 Decodable、Encodable 和 friend ,试图理解它背后的“魔法”。 以下是我发现不寻常的一件事: class Person: Decodable { var n
在 Swift 书中,枚举的例子很好用 enum CompassPoint: String { case north, south, east, west } var northCom = C
我是一名优秀的程序员,十分优秀!