1

私はいくつかの iPhone プログラミングを試していて、退役軍人にはかなり明白かもしれない何かに出くわしましたが、なぜそれが起こっているのか正確にはわかりません. 2 つの UIViewController クラスがあり、他のクラスからメソッドにアクセスしたいと考えています。IB でそれらの両方に関連付けられた 2 つの NSObject クラスがあり (クラス ファイルはそれぞれ UpdateClass として)、クラスを作成してメソッドを呼び出そうとしています。かなり簡単に思えますが、問題は、(NSLog によると) メソッドを呼び出しているが、ラベルを更新していないことです。これが私のコードです:

//UpdateClass.h
#import <Foundation/Foundation.h>

@interface UpdateClass : NSObject {
    IBOutlet UILabel *lbl1;
    IBOutlet UILabel *lbl2;
}

@property (nonatomic, retain) IBOutlet UILabel *lbl1;
@property (nonatomic, retain) IBOutlet UILabel *lbl2;

- (void)updateLabels;

@end

//UpdateClass.m

#import "UpdateClass.h"

@implementation UpdateClass

@synthesize lbl1;
@synthesize lbl2;


- (void)updateLabels {
    NSString *someWord = @"Whatever"; // This could be anything
    NSLog(@"NSObject Update");
    [lbl1 setText:someWord];
    [lbl2 setText:someWord];
}


@end

//ViewController1.h
#import <UIKit/UIKit.h>
@class UpdateClass;
@interface ViewController1 : UIViewController {
IBOutlet UIButton *button1;
NSObject *UpdateClassObject;
UpdateClass *updateClass;
}
@property (nonatomic, retain) IBOutlet UIButton *button1;
@property (nonatomic, retain) NSObject *UpdateClassObject;
@property (nonatomic, retain) UpdateClass *updateClass;
- (void)updateLabels:(id)sender;
@end

//ViewController1.m
#import "ViewController1.h"
#import "UpdateClass.h"

@implementation ViewController1
@synthesize button1;
@synthesize UpdateClassObject;
@synthesize updateClass;

- (void)viewDidLoad {
    [super viewDidLoad];
    updateClass = [[UpdateClass alloc] init];
}

- (void)updateLabels:(id)sender; { //This is connected to TouchDown on button1
    NSLog(@"Calls UpdateLabels");
    [updateClass updateLabels]; //Calls the class method
}

//ViewController2.h
#import <UIKit/UIKit.h>
@class UpdateClass;
@interface ViewController2 : UIViewController {
IBOutlet UIButton *button2;
NSObject *UpdateClassObject;
UpdateClass *updateClass;
}
@property (nonatomic, retain) IBOutlet UIButton *button2;
- (void)updateLabels:(id)sender;
@end

//ViewController2.m
#import "ViewController2.h"
#import "UpdateClass.h"

@implementation ViewController2
@synthesize button2;
@synthesize UpdateClassObject;
@synthesize updateClass;

- (void)viewDidLoad {
    [super viewDidLoad];
    updateClass = [[UpdateClass alloc] init];
}

- (void)updateLabels:(id)sender; { //This is connected to TouchDown on button2
    NSLog(@"Calls UpdateLabels");
    [updateClass updateLabels]; //Calls the class method
}

したがって、両方のビューの IB に接続された NSObject があります。NSObject とファイルの所有者に接続された各ビューにはラベルがあります (両方に接続する必要はないかもしれません)。ボタンが押されると (これも IB で適切に接続されます)、ラベルは何らかの文字列に変更されるはずです。NSLog は、メソッドが呼び出されたことを報告しますが、ラベルは変更されません。ここで何が問題なのですか?

(注:現時点ではすべてのコードを持っていないため、これを入力する必要があったため、小さな間違いがある可能性があります)。

4

4 に答える 4

1

ここでデザインについて一言:

2 つ以上のビュー コントローラーの実装間でいくつかの機能を共有したいようです。この場合、UIViewController から派生する共通の基本クラスを作成し、そのクラスから 2 つのビューを派生させることができます。BaseView は、IB で接続できる一般的な UI コンポーネントのアウトレットを宣言します。

@interface BaseUIViewController : UIViewController {
    IBOutlet UILabel *lbl1;
    IBOutlet UILabel *lbl2;
}

@property (nonatomic, retain) IBOutlet UILabel *lbl1;
@property (nonatomic, retain) IBOutlet UILabel *lbl2;

- (void)updateLabels;

@end

...

@interface ViewController1 : BaseUIViewController {
    IBOutlet UIButton *button1;

...

于 2009-07-24T17:41:40.230 に答える
0

NSLog()実行してもラベルが更新されない場合、それはほぼ確実でlbl1ありlbl2、ゼロです。それらは実際にはIBに接続されていないか、実行する前にこのコードを-viewDidLoad実行しているため、ほぼ確実にゼロになります。-updateLabelsここでの設計では、ビューが実際にアウトレットをロードして配線するまで回避する必要があります。ビューは遅延して読み込まれるため、これらのラベルは、ビューを初めて表示する直前まで作成されません。

短いバージョンでは、おそらくで呼び出す必要があり-updateLabelsます-viewDidLoad

于 2009-07-24T17:24:33.887 に答える
0

このコードには混乱を招く部分がいくつかあるので、オブジェクトとクラスを明確に区別するところから始めましょう。

目的は何ですか:

NSObject *UpdateClassObject;

それは何ですか?どのように割り当てられますか (ペン先から?)? その名前から、UpdateClass クラスのインスタンスが必要なだけのように見えます。これは次の目的です。

UpdateClass *updateClass;

前者を使用していないように見えるので、なぜそこにあるのかまったくわかりません。

さて、あなたの問題の核心に移りましょう: あなたは呼び出し[updateClass updateLabels]を行っており、NSLog ステートメントはそれが実際に呼び出されていることを示しています。最も可能性の高い問題は、ラベルの両方のインスタンスでありlbl1lbl2実際にはnil. Objective-C では、(updateText:この場合のように) にメッセージを送信してnilもエラーは発生せず、黙って失敗するだけです。

では、なぜ彼らはゼロなのですか?まあ、それらは s として宣言されているので、メンバー変数に s を実際に接続IBOutletするファイル所有者が NIB ファイルを持っていると思います。これが正しければ、NIB で正しく初期化する必要があります。UpdateClassUILabelupdateClass

updateClass = [[UpdateClass alloc] initWithNibName:@"UpdateClass" bundle:nil]; // or whatever the nib is called

しかし、あなたが実際にやっていることは次のとおりです。

updateClass = [[UpdateClass alloc] init];

これは、クラスが NIB から初期化されることはなく、ラベルが配線されることもないことを意味します。

クラス名に「クラス」という単語を使用することは、かなり冗長です。明らかにクラスです。これはまた、混乱を招く可能性があります.inのインスタンスを格納しているインスタンス変数UpdateClassが呼び出されupdateClassます.Class[SomeClass class]

于 2009-07-24T17:26:43.553 に答える
0

updateLabels メッセージを間違った UpdateClass に送信しています。

IBにも設定されたラベルへの接続を持つInterfaceBuilderのUpdateClassのインスタンスを接続したと言いました。したがって、ビューが読み込まれると、NIB から既に挿入された UpdateClass オブジェクトが含まれています。

viewDidLoad の実装で、UpdateClass の新しいインスタンスを作成します。そのインスタンスにはラベルが設定されていません (nil です)。したがって、 updateLabels メソッドをそのオブジェクトに送信すると、そのオブジェクトには更新するラベルがなくなります。

viewDidLoad で updateClass の宣言と割り当てを破棄し、updateLabels メッセージを UpdateClassObject に送信するだけです。メンバー UpdateCLassObject の名前を updateClass に変更するか、クラスの名前を updater のような名前に変更することを検討してください。代わりに基底クラスを使用することも検討してください。

于 2009-07-24T17:35:24.363 に答える