0

カスタム プロトコルのデリゲートを設定しようとしています。これには、必要なメソッドが 1 つあり、オブジェクトの配列をtwo の階層に戻すUITableViewControllersことができます。私の代理人は引き続き戻ってきnilます。このため、必要なメソッドが呼び出されることはありません。

my を使用したデータソースとデリゲートの実装がUITableViewControllers競合を引き起こしているかどうか疑問に思っています。また、デリゲートを宣言するときに ARC が邪魔をしているのではないでしょうか?

UITableViewControllersどちらも Storyboard を使用して構築されており、セグエを使用してナビゲートされていることに注意してくださいUINavigationController(これが問題を引き起こしているかどうかは不明です)。

ナビゲーションは --> AlarmViewController-->AlarmDetailsViewControllerです。Alarmアラームのすべての詳細を含むオブジェクトを myに作成し、AlarmDetailsViewControllerそれを配列に配置して、その配列を myに戻しAlarmViewController、テーブルのカスタム セルに表示したいと考えています。

注:ここではデリゲート パターンを使用します。クラス を呼び出しNSNotificationsたり使用したりするソリューションには興味がありません。AppDelegate

AlarmDetailsViewController.h

#import "Alarm.h"

@protocol PassAlarmArray <NSObject>
   @required
   -(void) passAlarmsArray:(NSMutableArray *)theAlarmsArray;
@end

@interface AlarmDetailsViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate> 
{
   //.....   
   id <PassAlarmArray> passAlarmsArrayDelegate;   
}

@property (nonatomic, retain) id <PassAlarmArray> passAlarmsArrayDelegate;

@end

AlarmDetailsViewController.m

#import "AlarmDetailsViewController.h"

@interface AlarmDetailsViewController ()

@end

@implementation AlarmDetailsViewController

@synthesize passAlarmsArrayDelegate;

-(void) viewWillDisappear:(BOOL)animated
{
   NSLog(@"delegate = %@", self.passAlarmsArrayDelegate);  // This prints nil
   [[self passAlarmsArrayDelegate] passAlarmsArray:alarmsArray]; 
}
//....
@end

AlarmViewController.h

@interface AlarmViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, PassAlarmArray>
{
//...
AlarmDetailsViewController  *alarmDetailsViewController;
}

@property (nonatomic, retain) AlarmDetailsViewController *alarmDetailsViewController;

@end

AlarmViewController.m

#import "AlarmViewController.h"
#import "AlarmDetailsViewController.h"
#import "AlarmTableViewCell.h"
#import "Alarm.h"

@interface AlarmViewController ()

@end

@implementation AlarmViewController

@synthesize alarmDetailsViewController;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // This is where I'm attempting to set the delegate
    alarmDetailsViewController = [[AlarmDetailsViewController alloc]init];
    [alarmDetailsViewController setPassAlarmsArrayDelegate:self];
}

//....

//My @required protocol method which never gets called since my delegate is nil
-(void) passAlarmsArray:(NSMutableArray *)theAlarmsArray 
{
    alarmsTableArray = theAlarmsArray;
    NSLog(@"alarmsTableArray contains:  %@", alarmsTableArray); // Never gets called due to delegate being nil
    NSLog(@"theAlarmsArray contains:  %@", theAlarmsArray); // Never gets called due to delegate being nil
}

@end

(viewDidLoad メソッドとは対照的に) AlarmViewController でボタンが押されたときに起動するメソッドでデリゲートを設定しようとしましたが、それも機能しません。

ここのどこかでロジック フロー エラーが発生したと想定しています。. . しかし、ほぼ 2 日間の捜索と再構築で発見されていません。うーん。

4

3 に答える 3

1

デリゲートを間違った場所に設定し、セグエを実行したときに取得するものとは異なるコントローラーのインスタンスに設定しています。AlarmViewController から AlarmDetailsViewController をプッシュする場合は、prepareForSegue メソッドでデリゲートを設定する必要があります。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    AlarmDetailsViewController *alarm = segue.destinationViewController;
    alarm.passAlarmsArrayDelegate = self;
}

ビュー コントローラーのライフ サイクル、いつ、どのようにインスタンス化され、いつ消滅するかを理解する必要があります。これは iOS プログラミングの心臓部であり、Apple はそれに関する広範なドキュメントを用意しています。セグエを読むことも非常に役立ちます。セグエ (アンワインド セグエ以外) は、常に宛先コントローラーの新しいインスタンスをインスタンス化します。そのため、セグエが実行されると、ボタンから直接、またはコードで、新しい (直接割り当てたものとは異なる) 詳細コントローラーがインスタンス化されます。そのセグエが実行される前に、prepareForSegue: が呼び出され、作成しようとしているセグエにアクセスできるようになります。これは、デリゲートを設定したり、宛先ビュー コントローラーに情報を渡したりする場所です。

于 2013-02-02T07:09:24.657 に答える
0

ARC を使用しているため、(非原子、保持) を (非原子、強力) に置き換えてみましたか?

于 2013-02-01T22:26:20.163 に答える
0

alarmDetailsViewController プロパティのような自動合成されたプロパティには、_alarmDetailsViewController などのように、アンダースコアが前に付いたバッキング ivar があります。alarmDetailsViewController ivar (AlarmViewController.h の @interface ... {} ブロック内で宣言された alarmDetailsViewController) は、alarmDetailsViewController プロパティのバッキング ivar とは異なります。

alarmDetailsViewController ivar を削除し、できれば self.alarmDetailsViewController を通じて @property を使用してください。

于 2013-02-01T22:26:36.210 に答える