我知道什么时候该用哪个,但确切的用法我还是不清楚。有人能举例说明吗?
z9smfwbn1#
如果只想与一个对象对话,请使用委托。例如,一个tableView有一个委托-只有一个对象应该负责处理它。如果你想告诉所有人发生了什么事,就使用通知。例如,在内存不足的情况下,系统会发送通知,告知您的应用出现内存警告。因为应用中的许多对象可能希望降低其内存使用量,所以它是一个通知。我不认为KVO是一个好主意,尽量不要使用它,但是,如果你想知道一个属性是否发生了变化,你可以监听它的变化。希望能帮上忙。PS This sums up why I think KVO is broken
mbskvtky2#
当存在“主/从”关系(委托知道类,类知道委托)时,使用委托,其中一个类在控件层次结构中更高,并且当很明显不会有其他元素(主要是UI)对知道类必须说什么感兴趣的情况时。当班级不想知道谁在听以及有多少人在听时,使用通知,任何人和任何号码都可以注册通知。KVO在“不被全班知道”的情况下听是有用的,当然情况并非如此,应用KVO的班级不需要改变。
3pmvbmvn3#
委托是一种设计模式,当您希望其他对象修改发送方的行为时可以使用它。例如:终端窗口避免显示任何被窗口边缘剪裁的行或字符,因为终端窗口的代理会更改窗口的大小以确保这一点。通知是在不需要响应时使用的一种模式。示例:您收到系统即将进入睡眠状态的通知。通知的发送者并不关心你对它做了什么。
6psbrbz94#
即使这三种方式都能满足你的需要,委派仍然是一个更好的选择:1.可重复使用性。1.自我记录。通过检查类的头文件,可以立即识别出交换的数据是什么/如何发生的。
ryhaxcpt5#
iOS代理模式、通知中心、KVO代理人
delegate模式是一种设计模式,它可以与Structural(GoF的Decorator或Wrapper模式)相关,它在不改变代码的情况下向对象添加行为和责任。Yo可以将一些逻辑移到另一个helper类中,或者将其用作 backbone 。它是继承的替代方案。从技术上讲,它使用的是associationAbout(https://stackoverflow.com/a/65967271/4770877)。Kotlin语言在语言层上支持delegate模式。对于iOS,通常用于Loose coupling,用于类Class1 <-> Class2之间的通信,而不包括Retain cycleAbout(https://stackoverflow.com/a/61020491/4770877),其中SomeClass1 -> SomeClass2和SomeClass2 weak-> SomeClass1
delegate
association
Loose coupling
Class1 <-> Class2
Retain cycle
SomeClass1 -> SomeClass2
SomeClass2 weak-> SomeClass1
protocol SomeProtocol: AnyObject { func foo() } class SomeClass1: SomeProtocol { let someClass2 = SomeClass2() init() { someClass2.delegate = self } func foo() { print("foo is called") } } class SomeClass2 { weak var delegate: SomeProtocol? func onButtonTap() { delegate?.foo() } }
字符串
通知中心
NotificationCenter or NSNotificationCenter(Objective-C)(非远程(推送)或本地通知)是publish/subscribe event bus的一种。您有一个NotificationCenter singleton对象,它是任何人都可以发送或接收事件的单个点。您可以使用它通过all应用程序发送事件,任何人都可以中断它。这种系统开发速度快,但支持难度大。它也是一种Loose coupling系统。您可以使用NotificationCenter的下一个API:
NotificationCenter or NSNotificationCenter(Objective-C)
publish/subscribe event bus
NotificationCenter
post(name: object: userInfo:) addObserver(_ observer: selector: name: object:) removeObserver(_ observer: selector: object:)
型例如,系统显示、隐藏键盘
NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) @objc func keyboardWillShow(_ notification:Notification) { } @objc func keyboardWillHide(_ notification:Notification) { }
型
千瓦
KVO-键值观察。正在观察Objective-C支持的属性值的更改。当您需要了解对象上的某些更改时,可以使用它,而无需任何请求
KVO
目标-C-@propertyAbout(https://stackoverflow.com/a/66233088/4770877),它使用willChangeValueForKey和didChangeValueForKey来表示KVO
@property
willChangeValueForKey
didChangeValueForKey
observeValueForKeyPath
#import "SomeClass.h" @interface SomeClass() @property (nonatomic, strong) NSString *someVariable; @end @implementation SomeClass - (void) foo { [self addObserver: self forKeyPath: @"someVariable" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: nil]; self.someVariable = @"set someVariable"; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"someVariable"]) { NSLog(@"%@", change); } } @end
斯威夫特-NSObject和@objc dynamicAbout(https://stackoverflow.com/a/60937714/4770877)
NSObject
@objc dynamic
class SomeClass1 : NSObject { @objc dynamic var v = 0 } class SomeClass2 { var kvoToken: NSKeyValueObservation? func subscribe(someClass1: SomeClass1) { kvoToken = someClass1.observe(\.v, options: .new) { (object, change) in guard let value = change.newValue else { return } print("New value: \(value)") } } deinit { kvoToken?.invalidate() } }
型或者是
public class SomeClass: NSObject public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { } } func foo() { someClass1.addObserver(self, forKeyPath: "v", options: .new, context: nil) }
型Objective-C KVC vs KVO(https://stackoverflow.com/a/67622702/4770877)的Swift KVC(https://stackoverflow.com/a/66163865/4770877)
u0njafvf6#
在我看来,KVO更好,因为它的零开销的优势。即使你没有使用/观察它们,通知也会有开销。为了改善这一点,你可以使用不同的通知中心,但即使这样,一些开销将在那里(纠正我,如果我错了)。KVO有点复杂,但当你必须观察很多东西时,它是值得的。
6条答案
按热度按时间z9smfwbn1#
如果只想与一个对象对话,请使用委托。例如,一个tableView有一个委托-只有一个对象应该负责处理它。
如果你想告诉所有人发生了什么事,就使用通知。例如,在内存不足的情况下,系统会发送通知,告知您的应用出现内存警告。因为应用中的许多对象可能希望降低其内存使用量,所以它是一个通知。
我不认为KVO是一个好主意,尽量不要使用它,但是,如果你想知道一个属性是否发生了变化,你可以监听它的变化。
希望能帮上忙。
PS This sums up why I think KVO is broken
mbskvtky2#
当存在“主/从”关系(委托知道类,类知道委托)时,使用委托,其中一个类在控件层次结构中更高,并且当很明显不会有其他元素(主要是UI)对知道类必须说什么感兴趣的情况时。
当班级不想知道谁在听以及有多少人在听时,使用通知,任何人和任何号码都可以注册通知。
KVO在“不被全班知道”的情况下听是有用的,当然情况并非如此,应用KVO的班级不需要改变。
3pmvbmvn3#
委托是一种设计模式,当您希望其他对象修改发送方的行为时可以使用它。例如:终端窗口避免显示任何被窗口边缘剪裁的行或字符,因为终端窗口的代理会更改窗口的大小以确保这一点。
通知是在不需要响应时使用的一种模式。示例:您收到系统即将进入睡眠状态的通知。通知的发送者并不关心你对它做了什么。
6psbrbz94#
即使这三种方式都能满足你的需要,委派仍然是一个更好的选择:
1.可重复使用性。
1.自我记录。通过检查类的头文件,可以立即识别出交换的数据是什么/如何发生的。
ryhaxcpt5#
iOS代理模式、通知中心、KVO
代理人
delegate
模式是一种设计模式,它可以与Structural(GoF的Decorator或Wrapper模式)相关,它在不改变代码的情况下向对象添加行为和责任。Yo可以将一些逻辑移到另一个helper类中,或者将其用作 backbone 。它是继承的替代方案。从技术上讲,它使用的是association
About(https://stackoverflow.com/a/65967271/4770877)。Kotlin语言在语言层上支持delegate
模式。对于iOS,通常用于Loose coupling
,用于类Class1 <-> Class2
之间的通信,而不包括Retain cycle
About(https://stackoverflow.com/a/61020491/4770877),其中SomeClass1 -> SomeClass2
和SomeClass2 weak-> SomeClass1
字符串
通知中心
NotificationCenter or NSNotificationCenter(Objective-C)
(非远程(推送)或本地通知)是publish/subscribe event bus
的一种。您有一个NotificationCenter
singleton对象,它是任何人都可以发送或接收事件的单个点。您可以使用它通过all应用程序发送事件,任何人都可以中断它。这种系统开发速度快,但支持难度大。它也是一种Loose coupling
系统。您可以使用NotificationCenter的下一个API:
型
例如,系统显示、隐藏键盘
型
千瓦
KVO
-键值观察。正在观察Objective-C支持的属性值的更改。当您需要了解对象上的某些更改时,可以使用它,而无需任何请求目标-C-
@property
About(https://stackoverflow.com/a/66233088/4770877),它使用willChangeValueForKey
和didChangeValueForKey
来表示KVO
willChangeValueForKey
、didChangeValueForKey
,则不会触发observeValueForKeyPath
willChangeValueForKey
、didChangeValueForKey
型
斯威夫特-
NSObject
和@objc dynamic
About(https://stackoverflow.com/a/60937714/4770877)型
或者是
型
Objective-C KVC vs KVO(https://stackoverflow.com/a/67622702/4770877)的
Swift KVC(https://stackoverflow.com/a/66163865/4770877)
u0njafvf6#
在我看来,KVO更好,因为它的零开销的优势。即使你没有使用/观察它们,通知也会有开销。为了改善这一点,你可以使用不同的通知中心,但即使这样,一些开销将在那里(纠正我,如果我错了)。KVO有点复杂,但当你必须观察很多东西时,它是值得的。