视图控制器有时不会收到NSNotification

时间:2011-06-09 18:59:13

标签: iphone objective-c cocoa-touch nslog nsnotifications

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

我有一个导航控制器。

我有一个名为“添加”的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//

从View 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中打印,再也不打印?
  3. 代码:

    [[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
    

3 个答案:

答案 0 :(得分:3)

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

如果添加日志语句,当应该创建应该接收其中一个通知的对象以及在{{1}的主体内销毁时,您应该能够看到生命周期对收到的消息的影响(或者你的超类指定的初始值设定项)和-init

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

答案 1 :(得分: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];
}

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

答案 2 :(得分:1)

“第一次发送通知时,其他视图控制器不存在。它们尚未创建.viewController仍然是零。由于没有观察者对象,您没有得到任何日志第二次,视图控制器中的两个对象都已创建。因此,它们在活动时收到通知,并记录收到的通知声明。“