3

私が書いている OS X アプリで非常に基本的な初期化の問題があります。NSViewController の initWithNibName でインスタンス変数を初期化しています。ただし、これらの変数は値を失い、IBAction メソッドでアクセスするまでに nil に等しくなります。

これが私のコードです。1 つのメイン ウィンドウと 1 つの NSViewController を持つアプリケーションがあります。アプリ デリゲートは、applicationDidFinishLoading で initWithNibName をプログラムで呼び出しています。ビューが表示され、ビュー内のボタンが onButtonClick を正常に呼び出します。ただし、そのメソッドでは、myString の値は null です。ログは、initWithNibName メソッド中に正常に初期化されたことを明確に示しています。そのため、initWithNibName とボタンのクリックの間で値が失われました。

//MyAppDelegate.m
@implementation MyAppDelegate

@synthesize window; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    MainView* mainViewController = [[MainView alloc] initWithNibName:@"MainView" bundle:[NSBundle mainBundle]];
    [mainViewController loadView];
NSView *controllerView = [mainViewController view];
    [window setContentView:controllerView];
}

@end

//MainView.h
@interface MainView : NSViewController {
    NSButton *myButton;
    NSString* myString;
}

@property (assign) IBOutlet NSButton *myButton;
@property (assign) NSString* myString;

- (IBAction)onMyButtonClick:(id)sender;

@end

//MainView.m
@implementation MainView

@synthesize myButton;
@synthesize myString;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    NSLog(@"initWithNibName");
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code here.
        NSLog(@"Initializing...");
        [self setMyString:@"try to set the variable"];
        NSLog(@"String is %@", myString);
    }

    return self;
}

- (void)awakeFromNib {
    NSLog(@"awakeFromNib");
    //[self setMyString:@"init in here works, but is called too many times"];
}

- (IBAction)onMyButtonClick:(id)sender{
    NSLog(@"Button clicked");
    NSLog(@"%@", myString);  //Always nil when initialized in initWithNibName()!!
}

@end


//Logs

initWithNibName
Initializing...
String is try to set the variable
awakeFromNib
awakeFromNib
Button clicked
(null)

myString を取得してその値を保持するにはどうすればよいですか?

考えられるすべてのタイプのプロパティ宣言を試しました。また、さまざまな割り当て方法を試しました ([self setMyString]、self.myString = @"blah"、myString = [NSString stringWithFormat:@"blah"] など)。

awakeFromNib() で初期化を行う必要があることを読みました。これは実際に機能します。ただし、私の最終的な初期化コードには一連の [[MyObj alloc] init] 呼び出しが含まれ、それらが複数回呼び出されると、複数のポインターが生成され、そこから狂気が生じます。私の最終的な目標は、コントローラーが常に参照し、常に同じデータを取得できるオブジェクトへのポインターを 1 つ持つことです。オブジェクトはコントローラーによって初期化されます。コントローラーは参照を保持し、ユーザーがコントローラーを操作するときに必要に応じて更新します。

NSViewControllers のインスタンス変数を 1 回だけ初期化し、コントローラーの存続期間中その値を保持する方法はありますか?

ありがとう

ケブ

4

3 に答える 3

1

プロパティを (代入) ではなく (コピー) として宣言する必要があります

于 2011-12-21T13:53:19.407 に答える
0

それらを(非アトミック、保持)として宣言しようとしましたか?

于 2011-12-21T13:59:10.153 に答える
0

私の質問のコメントに正解が埋もれているので、これに答えさせてください。

私は自分が間違っていたことを理解しました。ビューのコントローラーを表す各ペン先にビューコントローラーを追加していました。次に、ボタンのクリックを別のビュー コントローラー オブジェクトにアタッチしました。@Francis-McGrew は、ボタンのクリックをファイル所有者にアタッチし、ファイル所有者をビュー コントローラーに設定する必要があることを示すプロジェクトを添付しました。代わりにファイル所有者をプレースホルダーとして使用できる場合、基本的に2番目のView Controllerをnibにインポートする必要はありません。

于 2011-12-22T00:38:02.030 に答える