initialization order with delegates and multiple view controllers is not working

31 Views Asked by At

I am trying to build a program where the MainController uses a delegate to pass data into a table inside TableViewController. I think I've initialized it correctly but LoadSN() does not trigger the delegate function (I do see it run). Does the initialization of the MainController and the TableViewController not playing well together? (maybe I am not understanding the order of initialization?)

MainController.h

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN
@class MainController;
@protocol MainDelegate <NSObject>

- (void)addMainEntry:(NSString *)patchName :(NSString *)filename;

@end
@interface MainController : NSWindowController
{
@private
    IBOutlet NSTextField *status;
    IBOutlet NSTextField *serialNumber;
}
@property (nonatomic, weak) id<MainDelegate> delegate;
-(IBAction)LoadSNBtn:(id)sender;
-(IBAction)saveBtn:(id)sender;

@end
NS_ASSUME_NONNULL_END

MainController.m

#import "MainController.h"

@implementation MainController

@synthesize delegate;

- (void)awakeFromNib
{
    //NSLog(@"%@",[status stringValue]);
    NSLog(@"awakeFromNib MainController");
    NSString* msg = @"Main Station: Scan or Enter Serial Number above.";
    msg = [NSString stringWithFormat:@"%@\n%@",[status stringValue], msg];
    [status setStringValue:msg];
    [status setDrawsBackground:YES];
    [status setSelectable:YES];
}
- (void)windowDidLoad {
    [super windowDidLoad];
    
    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
- (IBAction)LoadSNBtn:(id)sender
{
    NSLog(@"LoadSNBtn");
    [delegate addMainEntry:@"LoadName" :@"LoadFilename"];
}
- (IBAction)saveBtn:(id)sender
{
    
}
@end

TableViewController.h

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "MainController.h"
#import "mainImage.h"

NS_ASSUME_NONNULL_BEGIN

@interface TableViewController : NSObject <NSTableViewDataSource, MainDelegate>
{
    @public
    IBOutlet NSTableView *tableView;
    NSMutableArray *imageList;
}
@property (copy) NSMutableArray *imageList;
@property (weak) MainController *mainController;
@end

NS_ASSUME_NONNULL_END

TableViewController.m #import "TableViewController.h"

@implementation TableViewController
@synthesize imageList = _imageList;
@synthesize mainController = _mainController;

-(id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"tableViewController init");
        [_mainController setDelegate:self];
        _imageList = [[NSMutableArray alloc] init];
        mainImage *mainEntry = [[mainImage alloc] init];
        [mainEntry setValue:@"noFilename" forKey:@"filename"];
        
        [_imageList addObject:mainEntry];

    }
    return self;
}
- (void)awakeFromNib
{
    NSLog(@"awakeFromNib TableViewController");

}
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{   // this needs to return the number of rows that the array has so tableView can display all of them
    //NSLog(@"size: %i", [list count]);
    return [_imageList count];
    
}
-(id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{   // need to pass in table column and row and return the right data to display
    mainImage *entry = [_imageList objectAtIndex:row];
    NSString *identifier = [tableColumn identifier]; // need to find the column, either name/age
    //NSLog(@"identifier: %@", identifier);
    return [entry valueForKey:identifier];
}
-(void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
{
    mainImage *entry = [_imageList objectAtIndex:row];
    NSString *identifier = [tableColumn identifier];
    
    [entry setValue:object forKey:identifier];
}
-(void)addMainEntry:(NSString *)patchName :(NSString *)filename
{
    NSLog(@"inside adding main entry");
    [_imageList addObject:[[mainImage alloc] init]];
    mainImage *entry = [_imageList objectAtIndex:0];
    [entry setValue:patchName forKey:@"patchName"];
    [entry setValue:filename forKey:@"filename"];
    //NSLog(@"name: %@ filename: %@", [entry valueForKey:@"patchName"], [entry valueForKey:@"filename"]);
    
    [tableView reloadData];
}
@end
1

There are 1 best solutions below

2
Rob Napier On

This looks like TableViewController is loaded from a Storyboard or XIB (given the IBOutlet annotation). init isn't going to be called in that case. You'll need to put your logic in awakeFromNib, as you do for MainController.

You'll also need to make sure that you've actually wired the delegate property to TableViewController in the XIB. This is a very common thing to forget to do. Make sure that delegate isn't nil. If "nothing happens" then something is almost certainly nil.