无法使用带有两个UITableViewControllers的ARC使用UINavigationController设置自定义协议委托

时间:2013-02-01 22:22:41

标签: ios objective-c

我正在尝试为我的自定义协议设置委托,该协议有一个必需的方法,允许我在两个{{层次结构中传递 返回 的对象数组1}}。我的代表继续返回UITableViewControllers。因此,我从未调用过我需要的方法。

我想知道我的nil的数据源和委托实现是否会导致冲突。另外,ARC在声明委托时可能会受到阻碍?

应该注意的是,UITableViewControllers都是使用Storyboard构建的,并使用UITableViewControllers内的segues进行导航(不确定这是否会导致问题)。

导航是 - > UINavigationController - > AlarmViewController。我在AlarmDetailsViewController中创建了一个Alarm对象,其中包含警报的所有详细信息,将其放入数组中,我想将该数组返回传递给我的{{1}要显示在表格中的自定义单元格中。

注意:我想在此处使用委托模式。我对调用AlarmDetailsViewController或使用我的AlarmViewController类的解决方案不感兴趣。

AlarmDetailsViewController.h

NSNotifications

AlarmDetailsViewController.m

AppDelegate

AlarmViewController.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

AlarmViewController.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中按下按钮时触发(与viewDidLoad方法相反)但是也不起作用。

我假设我在某处出现了逻辑流错误。 。 。但是近2天的狩猎和重建还没有发现它。啊。

3 个答案:

答案 0 :(得分:1)

您将代理设置在错误的位置,并且设置在控制器的不同实例上,而不是您执行segue时获得的实例。如果从AlarmViewController中推送AlarmDetailsViewController,则应在prepareForSegue方法中设置委托

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

您确实需要了解视图控制器的生命周期,它们实例化的方式和时间,以及它们何时消失。这是iOS编程的核心,Apple有大量文档。阅读segues也非常有用。 segue(除了展开segue之外)总是实例化目标控制器的新实例。因此,当执行segue时,无论是直接从按钮还是在代码中执行,都会实例化一个新的(与您直接分配的init不同)。在执行segue之前,调用prepareForSegue:,当您有权访问要创建的那个时。这是设置委托或将任何信息传递到目标视图控制器的地方。

答案 1 :(得分:0)

您是否因为使用ARC而尝试替换(非原子,保留)(非原子,强)?

答案 2 :(得分:0)

像alarmDetailsViewController属性这样的自动合成属性具有带有下划线的支持ivars,例如_alarmDetailsViewController。您的alarmDetailsViewController ivar(在AlarmViewController.h中的@interface ... {}块内声明的alarmDetailsViewController)与alarmDetailsViewController属性的后备ivar不同。

只需删除你的alarmDetailsViewController ivar并使用@property,最好是通过self.alarmDetailsViewController。