0

クリックすると、別のクラスviewControllerへの参照を動的に作成し、その過程でそのパラメーターも設定するボタンを持つがあります。次のように for ループ内でこれを行います。viewControllerviewController

-(void) clickOnButton:(id)sender {


    for (PersonObject *checkPerson in [DataModel sharedInstance].personList) {

        if (((UIControl*)sender).tag == checkPerson.personID) {

            ParentViewController *parentView = [[NSClassFromString(checkPerson.childViewController) alloc] init];
            parentView.personName = checkPerson.name;
            NSLog(parentView.personName);
            [self.navigationController pushViewController:parentView animated:YES];


        }

    }

}

作成され、ユーザーが送信される先の viewController では、viewDidLoad メソッドに次のコードがあります。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    NSLog(@"Hello %@", personName);
    UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 150, 35)];
    [title setCenter:CGPointMake(self.view.frame.size.width/2, 27)];
    [title setBackgroundColor:[UIColor clearColor]];
    [title setTextAlignment:NSTextAlignmentCenter];
    [title setFont:[UIFont boldSystemFontOfSize:15]];
    [title setText:personName];
    [self.view addSubview:title];

}

コードを実行すると、最初の viewController は personName パラメータの NSLog に正しい出力を返しますが、2 番目の viewController ステートメントのメソッド viewDidLoad 内の NSLog() は、personName の値が nil であることを示しており、何も表示されません。 viewController の私のタイトルとして。

パラメーター personName は NSString 型で、親の viewController クラスと子の viewController クラスの両方にあります (この 1 つの親を拡張しているいくつかの viewController クラスがあります)。子 viewController オブジェクトを動的に作成し、親 viewController を使用して送信される正しいパラメータ値を取得するにはどうすればよいですか?

4

1 に答える 1

1

よくある間違いは、次のようなインターフェイスを持つように移行するView Controllerにインターフェイスを持つことです。

@interface MyViewController : UIViewController
{
    NSString *personName;
}
@property (nonatomic, retain) NSString *personName
@end

次に、明示的に合成しない実装、personNameまたは次の@synthesizeようなステートメントを持つ実装のいずれかです。

@implementation MyViewController

@synthesize personName = _personName;

// the rest of the implementation

@end

明示的に宣言されたステートメントがない場合、上記のステートメントのよう@synthesizeに自動的に合成されることに注意してpersonNameください。

この比較的無害なコードには問題があります。1 つは呼び出され、もう 1 つは合成されて と呼ばれる2 つのインスタンス変数になってしまうからです。personName_personName

本当にすべきことは、明示的に宣言された ivar を削除することです。したがって、次のように@interfaceなります。

@interface MyViewController : UIViewController
@property (nonatomic, retain) NSString *personName
@end

そして、@synthesizeステートメントを完全に省略するか、次のようにします。

@synthesize personName = _personName;

次に、コードは、アクセサーを介してプロパティを参照できます。

NSLog(@"Hello %@", self.personName);

または、インスタンス変数 (ivar) を使用できます。

NSLog(@"Hello %@", _personName);

(余談ですが、properties を設定するself.personNameときはアクセサ (例)を使用することをお勧めします。実際に ivar (例) を使用する必要があるのは、イニシャライザ メソッドと dealloc だけです。)_personName

ただし、結論として、インスタンス変数を明示的に定義しないでください。コンパイラに合成させて、この種の問題を排除します。また、プロパティのアクセサー メソッドを実際に使用するつもりである場合に、誤って ivar を使用することを最小限に抑えるために、先頭のアンダースコアを使用して ivar を合成することをお勧めします。

詳細については、『Advanced Memory Management Programming Guide』の「 Practical Memory Management 」を参照してください。

于 2012-12-16T06:28:59.450 に答える