视图控制器有时收不到 NSNotification

发布于 2024-11-14 14:50:13 字数 2143 浏览 7 评论 0原文

所以,我只是在各种情况下测试 NSNotifications,而这个令人困惑。如果您能帮助我理解 NSNotifications,我将不胜感激!

我有一个导航控制器。

我有一个名为“Add”的 UIBarButtonItem,它会发布通知 DidAddNotification

如果我单击“添加”,它会将我推送到 view2。

 // I add view2 as observer and write method for this and NSlog if it gets implemented //

我再次将自己推向视图 3。

// I add view3 as another observer and use the same method as the previous view and I NSlog if it gets implemented//

从视图 3,我 popToRootViewControllerAnimated:YES,然后返回到 1。并再次遵循相同的过程。

所以这就是控件的方式...

1 -> 2 -> 3 -> 1

if I press add again,

the control is again the same 1 -> 2-> 3-> 1

这是输出(NSLogs)

我第一次按添加:

2011-06-09 14:47:41.912 Tab[5124:207]  I am the notification in view2
2011-06-09 14:47:41.912 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1
  // No notification in view 3 ?? //  I am now back to view 1.

我再次按添加:

2011-06-09 14:47:51.950 Tab[5124:207] I am the notification in view3
2011-06-09 14:47:51.951 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1
 // No Notification in view 2 ??? // ... I am now back to view 1.

我再按添加一次:

2011-06-09 14:47:59.160 Tab[5124:207] I am the notification in view 3
2011-06-09 14:47:59.161 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1

 // No Notification in view 2 ??? //  ... I am now back to view 1.


And this goes on..

有人能告诉我为什么

  1. NSLog第一次没有在视图3中打印,但其他时间都打印?
  2. 为什么 NSLog 第一次在视图 2 中打印,然后再也没有打印过?

代码:

[[NSNotificationCenter defaultCenter] postNotificationName:@"DidAddNotification" object:self];  // I put this in the - (IBAction) for addData

- (void)didPressAdd:(NSNotification *)notification { //NSLogs// }

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPressAdd:) name:@"DidAddNotification" object:nil]; // I put this in the viewDidLoad of view 1 and view 2

So, I am just testing NSNotifications on a variety of cases and this one is confusing. I would appreciate it if you could help me understand NSNotifications !

I have a Navigation Controller.

I have a UIBarButtonItem called "Add", which posts notification DidAddNotification

If I click Add it pushes me to view2.

 // I add view2 as observer and write method for this and NSlog if it gets implemented //

I again push myself to view 3.

// I add view3 as another observer and use the same method as the previous view and I NSlog if it gets implemented//

From View 3, I popToRootViewControllerAnimated:YES and I get back to 1. and again follow the same procedure.

So this is how the control is ...

1 -> 2 -> 3 -> 1

if I press add again,

the control is again the same 1 -> 2-> 3-> 1

Here's the output (NSLogs) :

I press Add for the first time:

2011-06-09 14:47:41.912 Tab[5124:207]  I am the notification in view2
2011-06-09 14:47:41.912 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1
  // No notification in view 3 ?? //  I am now back to view 1.

I press Add again:

2011-06-09 14:47:51.950 Tab[5124:207] I am the notification in view3
2011-06-09 14:47:51.951 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1
 // No Notification in view 2 ??? // ... I am now back to view 1.

I press Add one more time:

2011-06-09 14:47:59.160 Tab[5124:207] I am the notification in view 3
2011-06-09 14:47:59.161 Tab[5124:207]  I pressed Add Button and I just sent a notification from view 1

 // No Notification in view 2 ??? //  ... I am now back to view 1.


And this goes on..

Could anyone tell me why

  1. NSLog did not print in view 3 for the first time but prints all other time?
  2. Why NSLog prints in view 2 for the first time and never prints it again ?

Code:

[[NSNotificationCenter defaultCenter] postNotificationName:@"DidAddNotification" object:self];  // I put this in the - (IBAction) for addData

- (void)didPressAdd:(NSNotification *)notification { //NSLogs// }

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPressAdd:) name:@"DidAddNotification" object:nil]; // I put this in the viewDidLoad of view 1 and view 2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

携君以终年 2024-11-21 14:50:13

您所描述的差异似乎是由于对象存活时间的变化所致。视图和视图控制器不会无限期地存在,并且不会在应用程序启动时全部创建。必须存在一个对象才能接收和记录通知。基本通知系统正在按预期工作。

如果您添加日志语句来宣布何时创建应该接收这些通知之一的对象以及何时在 -init (或者您的超类的指定初始值设定项是什么)和 -dealloc

另外:如果您使用执行日志记录的函数标记日志语句,例如 NSLog(@"%s:", __func__),那么您的日志语句将更容易追踪。编译器为每个包含函数名称的函数生成一个名为 __func__ 的字符串。

The differences you are describing seem to be due to changes in which objects are alive when. Views and view controllers do not exist indefinitely, and are not all created when the app starts. An object has to exist to receive and log a notification. The basic notification system is working as expected.

You should be able to see the effect of lifetime on the messages received if you add log statements announcing when an object that is supposed to receive one of these notifications is created and when it is destroyed within the body of -init (or whatever the designated initializer of your superclass is) and -dealloc.

Also: Your log statements will be easier to track down if you tag them with the function doing the logging like NSLog(@"%s: <message>", __func__). The compiler generates a string named __func__ for each function that contains the function's name.

薆情海 2024-11-21 14:50:13

我刚刚设置了一个基于导航的应用程序。在根控制器标头中,我得到了这个:

#import <UIKit/UIKit.h>

extern NSString * const EPNotification;

@interface RootViewController : UITableViewController {
}
@end

我所做的所有不同之处是设置了一个在整个代码中使用的字符串。然后在根实现文件中,我有这个(加上所有标准的东西):

#import "RootViewController.h"
#import "One.h"

NSString *const EPNotification = @"Notification"; // this will be the global string name for the notification

@implementation RootViewController


#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gotNotification:) name:EPNotification
                                           object:nil];

    UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStylePlain                                                          target:self action:@selector(sendNotification)];

    self.navigationItem.rightBarButtonItem = next;
    [next release];
}

- (void)sendNotification {
    NSDictionary *d = [NSDictionary dictionaryWithObject:@"view 1" forKey:@"sender"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification" object:self userInfo:d];
    One *o = [[One alloc] initWithNibName:@"One" bundle:nil];
    [self.navigationController pushViewController:o animated:YES];
    [o release];
}

- (void)gotNotification:(NSNotification *)note {
    NSLog(@"from %@", [[note userInfo] objectForKey:@"sender"]);
}

我有 3 个其他视图(分别是一、二和三),它们几乎完全相同。标题中没有任何内容(除了标准内容)。我将发布其中一个 .m 文件,以便您可以查看设置。

#import "One.h"
#import "Two.h"

@implementation One

- (void)viewDidLoad {
    [super viewDidLoad];
    UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStylePlain
                                                     target:self action:@selector(sendNotification)];

    self.navigationItem.rightBarButtonItem = next;
    [next release];
}

- (void)sendNotification {
    NSDictionary *d = [NSDictionary dictionaryWithObject:@"view 2" forKey:@"sender"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification" object:self userInfo:d];
    Two *t = [[Two alloc] initWithNibName:@"Two" bundle:nil];
    [self.navigationController pushViewController:t animated:YES];
    [t release];
}

老实说,差不多就是这样了。在我的第三节课上,我弹出到根控制器而不是创建一个新的视图控制器,但仅此而已。每次单击按钮时,它都会告诉您当前所在的视图,因此希望它能帮助您更好地了解通知的工作原理。

I just set up a navigation-based app. In the root controller header, I've got this:

#import <UIKit/UIKit.h>

extern NSString * const EPNotification;

@interface RootViewController : UITableViewController {
}
@end

All I really did different there was set up a string to be used throughout the code. Then in the root implementation file, I have this (plus all the standard stuff):

#import "RootViewController.h"
#import "One.h"

NSString *const EPNotification = @"Notification"; // this will be the global string name for the notification

@implementation RootViewController


#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gotNotification:) name:EPNotification
                                           object:nil];

    UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStylePlain                                                          target:self action:@selector(sendNotification)];

    self.navigationItem.rightBarButtonItem = next;
    [next release];
}

- (void)sendNotification {
    NSDictionary *d = [NSDictionary dictionaryWithObject:@"view 1" forKey:@"sender"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification" object:self userInfo:d];
    One *o = [[One alloc] initWithNibName:@"One" bundle:nil];
    [self.navigationController pushViewController:o animated:YES];
    [o release];
}

- (void)gotNotification:(NSNotification *)note {
    NSLog(@"from %@", [[note userInfo] objectForKey:@"sender"]);
}

I've got 3 other views (One, Two and Three, respectively), that are pretty much all exactly the same. Nothing in the header (besides the standard stuff). I'll post one of the .m files so you can see the setup.

#import "One.h"
#import "Two.h"

@implementation One

- (void)viewDidLoad {
    [super viewDidLoad];
    UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:@"next" style:UIBarButtonItemStylePlain
                                                     target:self action:@selector(sendNotification)];

    self.navigationItem.rightBarButtonItem = next;
    [next release];
}

- (void)sendNotification {
    NSDictionary *d = [NSDictionary dictionaryWithObject:@"view 2" forKey:@"sender"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification" object:self userInfo:d];
    Two *t = [[Two alloc] initWithNibName:@"Two" bundle:nil];
    [self.navigationController pushViewController:t animated:YES];
    [t release];
}

And honestly, that's pretty much it. On my class Three, I pop to the root controller instead of create a new view controller, but that's it. It tells you which view you're on with each click of the button, so hopefully it'll help you understand better how notifications work.

抱猫软卧 2024-11-21 14:50:13

“第一次发送通知时,其他视图控制器不存在。它们还没有创建。viewController 仍然是 nil。由于没有观察者对象,所以你不会收到任何日志。第二次周围,​​视图控制器中的两个对象都已创建,因此它们在活动时会收到通知,并记录收到的通知语句。”

"The first time when you send the notification, other view controllers don't exist. They haven't been created yet. The viewController is still nil yet. Since there is no observer object, you don't get any logs. Second time around, both objects in the view controllers have been created. So they receive the notification as they are alive and the log the received notification statements."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文