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
4

3 回答 3

3

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

如果您添加日志语句宣布何时创建应该接收这些通知之一的对象以及何时在-init(或任何指定的初始化程序的主体中销毁),您应该能够看到生命周期对收到的消息的影响你的超类是)和-dealloc

另外:如果您使用像NSLog(@"%s: <message>", __func__). 编译器__func__为每个包含函数名称的函数生成一个字符串。

于 2011-06-09T20:22:19.557 回答
1

我刚刚建立了一个基于导航的应用程序。在根控制器标头中,我有这个:

#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];
}

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

于 2011-06-09T20:27:02.750 回答
1

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

于 2011-06-14T19:02:01.973 回答