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;

次に、selectedSubjectの値がapplicationDidFinishLaunchingLTAppDelegate.m内に設定されます。今、私が持っている別のクラスからこれにアクセスしたいと思っています。これは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で呼び出される前にLTTableViewControllerのinitメソッドapplicationDidFinishLaunchingが呼び出されたように見えます。これに基づいて、LTTableViewController.minitの「TestSubject」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

-applicationDidFinishLaunchingたとえば、すべてのnibのオブジェクトが初期化されたときに呼び出されるため、ビューに関連するものの構築後に起動が終了します。これは、nibのオブジェクトのコンストラクターが他のnibのオブジェクトを使用しないことを意味します(デリゲートとコントローラーはnibで初期化されますよね?)。

コンストラクターの代わりに使用してみてください-awakeFromNib。両方のオブジェクトの構築後に呼び出されると思います。

の呼び出しを頻繁に回避しようとしている場合は((LTAppDelegate *)[[NSApplication sharedApplication] delegate])、関数スタックでメソッドパラメーターとして渡すことをお勧めします。サイクリックは防御とある程度の柔軟性を参照します。

于 2012-10-29T12:31:02.390 に答える
1

では null に設定されているためs、存在しません。つまり、null を出力します。プライベート変数が他のオブジェクトに依存している場合、コンストラクターでプライベート変数を設定することはお勧めできません。init-currentSubjectDetails

むしろ、他のオブジェクトがそれを使用する必要があることをコントローラーに明示的に伝えますSubject(たとえば、sプロパティとして扱います)。

または、((LTAppDelegate *)[[NSApplication sharedApplication] delegate]);毎回クエリを実行します。

于 2012-10-27T19:07:01.233 に答える