-2

Looked all the themes about accessing NSMuatableArray from different class and tried all the answers but still can't access that MutableArray from different class.

My code:

ViewController.m

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (strong, nonatomic) NSArray *printProductImages;
@property (strong, nonatomic) NSArray *printProductNames;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;

    _printProductImages = [NSArray arrayWithObjects:@"demo_1.jpg", @"demo_2.jpg", @"demo_3.jpg",nil];
    _printProductNames = [NSArray arrayWithObjects:@"text", @"text", nil];
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AnotherViewController *anotherVC = [[AnotherViewController alloc] init];

    switch (indexPath.row) {
        case 0:

           [anotherVC.array1 removeAllObjects]; // does not work and no error
           [anotherVC.array1 addObjectsFromArray:_printProductImages]; // does not work and no error

           [anotherVC.array2 removeAllObjects]; // does not work and no error
           [anotherVC.array2 addObjectsFromArray:_printProductNames]; // does not work and no error

           [self performSegueWithIdentifier:@"AnotherViewController" sender:self];

            NSLog(@"~~Row: 1");
            break;
        case 1:
            NSLog(@"~~Row: 2");
            break;
        default:
            break;
    }

AnotherViewController.h

@interface AnotherViewController: UIViewController

@property (strong, nonatomic) NSMutableArray *array1;
@property (strong, nonatomic) NSMutableArray *array2;

@end

AnotherViewController.m

@implementation AnotherViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    _array1 = [NSMutableArray arrayWithObjects:@"demo_3.jpg", @"demo_4", @"demo_1.jpg", @"demo_2.jpg",nil]; // I want to delete these objects and load new objects to this array
    _array2 = [NSMutableArray arrayWithObjects:@"BIG", @"SMALL", @"MEDIUM", @"SUPER GOOD", nil]; // I want to delete these objects and load new objects to this array
Ekta Padaliya
  • 5,743
  • 3
  • 39
  • 51
Edgar
  • 898
  • 2
  • 12
  • 36

3 Answers3

2

The anotherVC you created wasn't added to the view hierarchy, so its view property hasn't been accessed which means viewDidLoad in AnotherViewController hasn't been called before you modify anotherVC.array1, at that point, anotherVC.array1 is nil.

Try the code below, I manually access its view by anotherVC.view, it may not a good idea but I will show you the mechanism.

AnotherViewController *anotherVC = [[AnotherViewController alloc] init];
anotherVC.view; // access its view property so viewDidLoad will be called
switch (indexPath.row) {
    case 0:

       [anotherVC.array1 removeAllObjects];
       [anotherVC.array1 addObjectsFromArray:_printProductImages];
       [anotherVC.array2 removeAllObjects];
       [anotherVC.array2 addObjectsFromArray:_printProductNames];

       [self performSegueWithIdentifier:@"SquarePhotos" sender:self];

        NSLog(@"~~Row: 1");
        break;
    case 1:
        NSLog(@"~~Row: 2");
        break;
    default:
        break;
}

BTW you'd better create the NSMutableArray in AnotherViewController's init method.

- (id) init 
{
    self = [super init]  ;
    if (self) {
        _array1 = [NSMutableArray arrayWithObjects:@"Some Objects",nil]; 
        _array2 = [NSMutableArray arrayWithObjects:@"Some Objects", nil]; 
    }
    return self; 
}
KudoCC
  • 6,912
  • 1
  • 24
  • 53
  • - (void) init { //create arrays here? } – Edgar Apr 18 '15 at 10:30
  • Am I doing it right? NSLog shows that _array1/2 are nil... `@implementation SquarePhotosViewController - (id) init { _array1 = [NSMutableArray arrayWithObjects:@"Some Objects",nil]; _array2 = [NSMutableArray arrayWithObjects:@"Some Objects", nil]; return self; }` even if I dont remove objects - [anotherVC.array1/2 removeAllObjects]; – Edgar Apr 18 '15 at 11:26
  • @Edgar No, I edited my answer added the init method. – KudoCC Apr 18 '15 at 11:58
1

This line is your big problem,

 AnotherViewController *anotherVC = [[AnotherViewController alloc] init];

This creates an instance of AnotherViewController that has nothing to do with the one you're segueing to -- it is never on screen, and will be deallocated right after didSelectRowAtIndexPath: finishes. You should get a reference to the instance that you're segueing to, which you get in prepareForSegue (there's no need to implement didSelectRowAtIndexPath: at all).

It's not clear to me, why you create the 2 arrays in AnotherViewController, then remove all the objects in them when you segue to that controller. That will not work anyway, unless you create the array in the controller's init method, since at the time of prepareForSegue, the destination view controller's view has not yet been loaded. If that's what you want to do though, you can do it like this (this assumes that you make the segue directly from the cell to AnotherViewController),

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    if ([segue.identifier isEqualToString:@"AnotherViewController"]) {
        AnotherViewController *anotherVC = segue.destinationViewController;
        switch (indexPath.row) {
            case 0:
               [anotherVC.array1 removeAllObjects];
               [anotherVC.array1 addObjectsFromArray:_printProductImages];
               [anotherVC.array2 removeAllObjects];
               [anotherVC.array2 addObjectsFromArray:_printProductNames];

               NSLog(@"~~Row: 1");
               break;
            case 1:
                NSLog(@"~~Row: 2");
                break;
            default:
                break;
        }
   }
}

In AnotherViewController, move the creation of your 2 arrays (which need to be mutable arrays) into the initWithCoder: method

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • is totally correct. prepare for segue is the place you pass your object properties around and is the best answer on this question – latenitecoder Nov 29 '16 at 09:59
0

This is where we set viewcontroller ID
Set any viewcontrollerID [same as storyboardID in image] for AnotherViewController in UI

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
       AnotherViewController *anotherVC = [storyboard instantiateViewControllerWithIdentifier:@"Viewcontroller ID"];

    anotherVC.array1=[[NSmutablearray alloc]init];

Then try

switch (indexPath.row) {
        case 0:

           [anotherVC.array1 removeAllObjects]; // does not work
           [anotherVC.array1 addObjectsFromArray:_printProductImages];

           [anotherVC.array2 removeAllObjects]; // does not work
           [anotherVC.array2 addObjectsFromArray:_printProductNames];

           [self performSegueWithIdentifier:@"SquarePhotos" sender:self];

            NSLog(@"~~Row: 1");
            break;
        case 1:
            NSLog(@"~~Row: 2");
            break;
        default:
            break;
    }
DHEERAJ
  • 1,478
  • 12
  • 32