查看各种Apple示例(例如" 添加音乐"),其中我看到它们将观察者添加到默认值NSNotificationCenter 中viewDidLoad,然后将其删除dealloc.这看起来很危险,viewDidLoad可以多次dealloc调用而不需要调用.然后,这将多次添加相同的观察者,导致多次调用处理程序.
解决这个问题的方法是删除观察者viewDidUnload,但这意味着同一个观察者可能会被移除第二次,dealloc这似乎是一个潜在的问题.
我错过了什么?
unrecognized selector每次Notification到达时我都会崩溃并收到错误,而App会尝试执行其关联的方法.这是我的代码 - 在viewDidLoad:
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: Selector(("sayHello")), name:NSNotification.Name(rawValue: "dataDownloadCompleted"), object: nil)
Run Code Online (Sandbox Code Playgroud)
该sayHello()方法是相当简单的-看起来是这样的:
func sayHello() {
print("Hello")
}
Run Code Online (Sandbox Code Playgroud)
我已经确认已Notification成功发布并且成功到达 - 所以这不是问题.当App试图Notification通过执行该sayHello()方法时到达时,就会发生崩溃.它一直给我这个unrecognized selector错误.
我有什么想法我做错了吗?(顺便说一句,这与Swift 3和Xcode 8完美配合,但现在使用Swift 4和Xcode 9语法已经改变了[Xcode让我完成了必要的代码修复/更新] - 但崩溃仍在继续.)
是否可以将观察者添加到简单变量(如BOOL或NSIntegers)中,并查看它们何时发生变化?
谢谢!
我有一个子视图向其父视图发送通知的情况.现在,我打电话给addObserver:在viewWillAppear:和removeObserver:中viewWillDisappear:.但是,我猜这是不正确的,因为viewWillAppear:视图刷新时调用.
[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject];
[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject];
Run Code Online (Sandbox Code Playgroud)
谢谢.
据我了解object,该addObserver方法的参数是您要从中接收通知的对象。大多数时候我认为它是nil(我认为这是因为所有对象都需要指定类型的通知)。在我的特定情况下,我在屏幕顶部和屏幕底部有一个文本字段,我希望视图仅在用户点击底部文本字段而不是顶部文本字段时向上移动。所以我调用以下方法viewWillAppear
func subscribeToKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: self.bottomTextField)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: self.bottomTextField)
}
Run Code Online (Sandbox Code Playgroud)
在keyboardWillShow:和keyboardWillHide:选择调用做视图的框架的重新定位方法。我尝试保留object参数,nil但会收到来自两个文本字段的通知。我尝试将object参数设置为self.bottomTextField(如上所示),但没有收到来自任一文本字段的通知。我的问题是双重的。首先,我addObserver是否正确理解了该方法(尤其是object参数),其次,为什么它没有从self.bottomTextField. 谢谢!
解决方案: 我知道这不是我所问的确切问题的解决方案,但我最终在仅单击底部文本字段时使视图向上移动的方法如下:
func subscribeToKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
Run Code Online (Sandbox Code Playgroud)
然后在keyboardWillShow:我有的方法中:
func keyboardWillShow(notification: NSNotification) {
if bottomTextField.editing { // only reset frame's …Run Code Online (Sandbox Code Playgroud) 一个非常简单的问题,但我似乎无法找到答案.(开发iOS 5+应用程序).
在我的AppDelegate中,我有一个属性,让我们称之为@property (non atomic) BOOL aFlag;.如果值发生变化,我希望我的AppDelegate得到通知.这是我尝试的(一切都发生在AppDelegate.m),这与我用观察者"链接"两个不同的对象时相同:
-(BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Some stuff
_aFlag = YES;
[self addObserver:self
forKeyPath:@"aFlag"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:nil];
// Some other stuff
}
-(void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
if ([keyPath isEqual:@"aFlag"]) {
// Do something
} else {
// Do nothing
}
}
Run Code Online (Sandbox Code Playgroud)
但是observeValueForKeyPath:不叫.
我哪里错了?谢谢.
当应用程序变为活动状态时,我正在使用UIApplicationDidBecomeActiveNotification刷新我的tableview.我的问题是,在我的ViewWillAppear中,我还调用了一个刷新该表数据的方法.
这导致在应用程序启动时刷新表两次.在应用程序最初启动时,如何让其中一个不要触发?刷新表有一些密集的网络和本地数据处理..所以我真的希望o只执行一次此操作.
谢谢.
我对观察者和 Swift/ObjC 还很陌生,我正在尝试使用 Apple 文档中所说的方法来监视 AVPlayer 状态,但是当我尝试添加时,我得到的一切都是“已收到消息但未处理”错误消息观察者。
gs_mediaObjAdv=AVPlayer(URL: NSURL(string: mediaURL));
gs_mediaObjAdv.addObserver(self, forKeyPath: "status", options:NSKeyValueObservingOptions.New, context:nil);
Run Code Online (Sandbox Code Playgroud)
如果我取消注册观察者,错误就会消失,但如果我在observeValueForKeyPath函数中添加println("test"),则不会发生任何事情。
关于如何以简单的方式监控状态的任何想法?
我从viewController中删除名为"myBrowser"的观察者时遇到问题.我有一个ProgressView栏,这是我添加观察者的代码:
webView!.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)
Run Code Online (Sandbox Code Playgroud)
在这个控制器中,我有一个按钮,让我回到另一个控制器:
@IBAction func disa(sender: UIBarButtonItem) {
self.navigationController?.popViewControllerAnimated(true)
}
Run Code Online (Sandbox Code Playgroud)
如果我加
webView?.removeObserver(self, forKeyPath: "estimatedProgress")
Run Code Online (Sandbox Code Playgroud)
在disa func中,我的应用程序崩溃,因为"WKWebView被解除分配,而键值观察者仍然注册了它"...我尝试将viewOidDisapper中的removeObserver放在viewWillDisappear中,但是如果我在progressView栏完全加载之前按下按钮我的应用程序仍会崩溃.
我该如何解决这个问题?
addobserver ×9
ios ×3
iphone ×3
objective-c ×3
swift ×3
avplayer ×1
cocoa ×1
dealloc ×1
self ×1
swift2 ×1
uitextfield ×1
xcode ×1
xcode9 ×1