0

我正在尝试从另一个类访问我的应用程序委托中的属性(我认为这很简单),但我在这样做时遇到了麻烦。我的文件目前看起来像这样:

LTAppDelegate.h

#import <Cocoa/Cocoa.h>
#import "Subject.h"

@interface LTAppDelegate : NSObject <NSApplicationDelegate, NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate> {

}

@property Subject *selectedSubject;

@end

LTAppDelegate.m

@synthesize selectedSubject;

然后applicationDidFinishLaunching在 LTAppDelegate.m 中设置 selectedSubject 的值。现在我想从我拥有的另一个类中访问它,该类称为 LTTableViewController 并且设置如下:

LTTableViewController.h

#import <Foundation/Foundation.h>
#import "LTAppDelegate.h"
#import "Subject.h"
#import "Note.h"

@interface LTTableViewController : NSObject{
    NSMutableArray *notesArray;
    LTAppDelegate *appDelegate;
    Subject *s;
}

-(IBAction)currentSubjectDetails:(id)sender;

@end

LTTableViewController.m

#import "LTTableViewController.h"

@implementation LTTableViewController

- (id)init
{
    self = [super init];
    if (self) {
        appDelegate = ((LTAppDelegate *)[[NSApplication sharedApplication] delegate]);

        s = [appDelegate selectedSubject];
        NSLog(@"Test Subject: %@", [s title]);

    }
    return self;
}

-(IBAction)currentSubjectDetails:(id)sender{
    NSLog(@"Selected Subject: %@", [s title]);

}

在插入各种 NSLog() 消息之后,会出现在 LTAppDelegate 中调用之前applicationDidFinishLaunching调用了 LTTableViewController 的 init 方法。基于此,LTTableViewController.m init 中的“测试主题”NSLog() 显示 null 是有意义的;但是,“currentSubjectDetails”方法链接到界面上的按钮,当应用程序完成加载后按下该按钮时,NSLog() 消息仍返回 null。

有什么明显的我在这里想念的吗。我觉得我有点愚蠢,错过了一些非常基本的东西。

4

3 回答 3

2

此处描述了类似的问题http://iphonedevsdk.com/forum/iphone-sdk-development/11537-viewcontroller-called-before-applicationdidfinishlaunching.html通常不建议在构造函数中添加这种功能。一般来说,我建议使用参数而不是依赖隐藏的依赖项,因为这些依赖项必然取决于执行顺序,并且您会失去编译器的帮助以避免无效值。视图控制器初始化器不应该用于存储可变引用,因为视图控制器由预定义的构造函数自动初始化,并且您不能以这种方式将参数传递给它们。

如果您需要访问应用程序委托,则获取它,对其执行操作并删除引用。尽量不要缓存它,你很可能会引入隐藏的问题。如果查看的内容取决于任何类型的当前状态,我建议您加入出现-消失周期。

于 2012-10-27T11:44:04.677 回答
1

嗯,s不存在,因为在中设置为null init,所以-currentSubjectDetails打印null。如果私有变量依赖于其他对象,那么在构造函数中设置它们不是一个好主意。

相反,让其他对象明确告诉您的控制器它应该使用它Subject(例如,将s其视为属性)。

或者,((LTAppDelegate *)[[NSApplication sharedApplication] delegate]);每次都查询。

于 2012-10-27T19:07:01.233 回答
1

-applicationDidFinishLaunching例如,在所有 nib 的对象初始化时调用,因此在构建视图相关内容后将结束启动。这意味着 nib 对象的构造函数不会使用任何其他 nib 对象(您的委托和控制器使用 nib 初始化,对吗?)。

尝试使用-awakeFromNib而不是构造函数,我认为它会在构造两个对象后调用。

如果你想避免经常调用((LTAppDelegate *)[[NSApplication sharedApplication] delegate])我建议将它作为方法参数传递给函数堆栈。循环引用防御和一些灵活性。

于 2012-10-29T12:31:02.390 回答