0

I have two view controllers: BSViewController which contains the source ivars number and array, and BSotherViewController which as the target needs to receive the ivars . One way of producing the desired result was provided in this question. The suggestion was to compute the values of self.number and self.array in an init that overrides the designated init as shown here.

- (id)init {

    if (self = [super init]) {
        //Set values
        NSArray*  _array = [NSArray arrayWithObjects: @"manny",@"moe",nil];
        self.array = _array;
        self.number = 25;
    }
    return self;
}

But I don't know how this solution enables the computation of self.number or self.array within the original method (viewDidLoad); I am only able to get 0 and null for their two values in viewDidLoad with any approach I have tried.

In addition, the following line produces a warning issue that view is an unused variable.

BSViewController *view = [[BSViewController alloc] init];

So I am looking for an approach which first computes my ivars number and array and then executes the init(WithNumber) so that the same variables can be used in the target class BSotherViewController.

I thought a more direct approach would be not use init, but instead to use something like the following initWithNumber but I cannot seem to make that work with all the ARC requirements for using underscores, and my limited understanding of objective-c.

- (id)initWithNumber:(NSInteger)number array:(NSArray *)array
{
    self = [super init];
    if (self) {
        _number = number;
        _array = array;
        return self;
    }
    return nil;
}

For completeness, I will reproduce below most of the code that was produced in the answer for the previous question.

BSViewController.h

#import <UIKit/UIKit.h>

@interface BSViewController : UIViewController{
   // NSInteger number;
}

@property (nonatomic) NSInteger number;
@property (nonatomic, weak) NSArray * array;
// - (id)initWithNumber:(NSInteger)number array:(NSArray *)array;
@end

BSViewController.m

#import "BSViewController.h"
@interface BSViewController ()
@end
@implementation BSViewController
@synthesize number;
@synthesize array;
/*
- (id)initWithNumber:(NSInteger)number array:(NSArray *)array
{
    self = [super init];
    if (self) {
        _number = number;
        _array = array;
        return self;
    }
    return nil;
}
*/
- (id)init {
    if (self = [super init]) {
        NSArray*  _array = [NSArray arrayWithObjects: @"manny",@"moe",nil];
        self.array = _array;
        self.number = 25;
    }
    return self;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"self: %@", self);
    BSViewController *view = [[BSViewController alloc] init];  //Warning issued: unused variable
    NSLog(@"self number: %d", self.number);
    NSLog(@"self array: %@", self.array);
}
@end

BSotherViewController.h

#import <UIKit/UIKit.h>
@class BSViewController;
@interface BSotherViewController : UIViewController
@property (strong, nonatomic) BSViewController *aview;
@end

BSotherViewController.m

#import "BSotherViewController.h"
#include "BSViewController.h"
@interface BSotherViewController ()
@end

@implementation BSotherViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    BSViewController *aview = [[BSViewController alloc] init];
    NSLog(@"other view: %@", self.aview);
    NSLog(@"other number: %d", aview.number);
    NSLog(@"other array: %@", aview.array);
}
@end
Community
  • 1
  • 1
zerowords
  • 2,915
  • 4
  • 29
  • 44
  • The designated initializer for `BSViewController` is `initWithNibName:bundle:`, so you override that rather than `init`. – mipadi Mar 12 '13 at 21:47
  • In your other question, you said “`BSViewController` has a button on it that is segues to `BSotherViewController`”. Did you mean that you are using a storyboard and have created a segue from the button to a `BSotherViewController`? – rob mayoff Mar 12 '13 at 21:48
  • Yes, I am using a storyboard. Wrt mipadi's comment: Is that going to get me any closer to the answer I want. I think I should really be using a "model" class instead of a "controller" class but at this point I am just trying to get some sort of test to work. My two variables `number` and `array` are calculated in this VC and used in one other VC. I am merely trying to work out the logistics of getting them from the former to the latter. I had no idea I would have this much trouble. – zerowords Mar 12 '13 at 21:57
  • @mipadi are you suggesting that I need to override `initWithNibName:bundle:` or else I cannot make `number` and `array` into ivars available to `BSotherViewController`? No, that can't be what you mean, because using `init` accomplishes that. But are you saying something else that I am not understanding? – zerowords Mar 13 '13 at 11:16

1 Answers1

1

You're using a storyboard segue. The segue will create the destination view controller by loading it from the storyboard. There's no point in creating a -[BSotherViewController initWithNumber:array:] method, because the segue won't use it.

When the user triggers the segue by tapping the button, the system creates an instance of UIStoryboardSegue. This segue object has a destinationViewController property which will (in your case) be the BSotherViewController instance that is about to appear. The system sends a prepareForSegue:sender: message to the source view controller (your BSViewController), and passes the segue object as the first argument.

You need to implement prepareForSegue:sender: in BSViewController. In that method, you have access to both the source view controller (self) and the destination view controller (segue.destinationViewController), so you can pass data from one to the other.

First, add number and array properties to BSotherViewController. Then, add a method like this to BSViewController:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // The identifier here must match the one you assigned to the segue in the storyboard.
    if ([segue.identifier isEqualToString:@"GoingToOtherViewController"]) {
        BSotherViewController *destination = segue.destinationViewController;
        destination.number = self.number;
        destination.array = self.array;
    }
}

Finally, in -[BSotherViewController viewDidLoad], use the values of your new number and array properties to set the content of your views.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • That first paragraph in your answer puzzles me: I was not thinking of creating a `-[BSotherViewController initWithNumber:array:]` in `BSotherViewController`, but in `BSViewController`. Am I missing something? I am still digesting you answer, though. Thanks. – zerowords Mar 12 '13 at 22:16
  • Then I misunderstood your plan. I don't understand why you'd put that method on `BSViewController` either, since (I assume) `BSViewController` is being loaded from your storyboard, and the storyboard loader won't use your custom `initWithNumber:array:` method. – rob mayoff Mar 12 '13 at 22:23
  • I tried implementing your prepare for segue and I don't get any new errors, but I don't get the information from `BSViewController` to `BSotherViewController`, either. In my real app I get from the storyboard a url that has text that I parse in `BSViewController` and put into `array` and calculate `number` also. But then the results are needed for user reaction in `BSotherViewController`, too. – zerowords Mar 12 '13 at 22:32
  • Rob, upon re-re-re-reading your answer, I think you are absolutely on the right track and mostly understand my plan. The only part that I don't understand or agree with, is that "final" step where you say to use the `viewDidLoad` to set my values. Inside `viewDidLoad` I have `NSLog(@"other number: %d", self.number);` and `NSLog(@"other array: %@", self.array);`, but they are 0 and (null). I want to use their values in `BSotherViewController`, but cannot see them. What am I missing now, please? – zerowords Mar 13 '13 at 16:02
  • Folks, I have been finding other things get in the way of it all working. Most recently I have discovered that it makes a difference whether the segue involved is a push or a modal segue. When I embed the VCs involved in UINavigationControllers, only the push segue works, not the modals. I don't know why, but likely that has been an unseen problem in my approaches and questions. I wish I had realized that push vs modal could require code changes. Apple docs make it seem as if the only difference between push and modal segue is how the scenes appear visually. That's not enough. Thanks to all. – zerowords Mar 16 '13 at 21:42