14

I am facing a problem regarding to add Null or nil value in NSArray. Actually I am adding Null value because my array count is not same. I am adding three array in Custom TableViewCell two array are from webservice and one array is from database. I am saving IndexPath in core data and then retrieving it.

enter image description here

As shown in Image I am saving indexPath in String and convert it in NSInteger from DidSelectAtIndexPath and show it in cellForRowAtIndexPath. My problem is, it's getting override because it is stored in string. So that I save it in coredataa and retrieve it but I get problem for mismatch count of array in cellforrowatindexpath. My code is like this

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
         static NSString *STI=@"STI";
        AuditTableViewCell *cell = (AuditTableViewCell *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:STI];
        if (cell == nil)
        {
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"AuditTableViewCell" owner:self options:nil];
            cell = [nib objectAtIndex:0];
            cell.accessoryType=UITableViewCellAccessoryNone;
        }
        cell.audittitlelbl.text=[NSString stringWithFormat:@"%@",[idarray objectAtIndex:indexPath.row]];
        cell.auditdesclbl.text=[NSString stringWithFormat:@"%@",[namearray objectAtIndex:indexPath.row]];

        NSManagedObject *device2 = [devices objectAtIndex:indexPath.row];
        NSMutableArray *Checkarray=[devices valueForKey:@"Key"]; // Hear in this array I am getting Index count problem
        NSLog(@"Device =%@",device2);
        NSLog(@"Check Array =%@",Checkarray);
        if(indexPath.row == CurrentIndexPath)
        {
            cell.listlbl.text=GlobalString;
            [cell setBackgroundColor:[UIColor greenColor]];
        }

        return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
           CurrentIndexPath=indexPath.row;
            NSLog(@"Current Index Path =%ld",(long)CurrentIndexPath);
            GlobalIndexPath = [[NSString stringWithFormat: @"%ld", (long)CurrentIndexPath] mutableCopy];

            NSManagedObjectContext *context = [self managedObjectContext];

            if (self.device) {
                // Update existing device
                [device setValue:GlobalStringChk forKey:@"Key1"];
                [device setValue:GlobalIndexPath forKey:@"Key"];


            } else {
                // Create a new device
                NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:@"Device" inManagedObjectContext:context];
                [newDevice setValue:GlobalStringChk forKey:@"Key1"];
                [newDevice setValue:GlobalIndexPath forKey:@"Key"];
            }

            NSError *error = nil;
            // Save the object to persistent store
            if (![context save:&error]) {
                NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
            }



            [Audittable reloadData];



            NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Device"];
            self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
}

This is my code hear I am saving indexpath in coredata and retrieving it in array. I have a problem for count of array in cellforrowatindexpath. How can I add Null or nil value in array so that it count get same. My Array is a dynamic array.The main problem is that I need to change the colour of cell if user click on it.when I store the value in NSInteger and convert it into indexpath I can change the colour But only for one cell at a time.When I click on other cell integer value get override. So for that I save it to core data and retrive but when I fetch core data array in cellforrowatindexpath it crash because of different count .Thanks in Advance!

TT--
  • 2,956
  • 1
  • 27
  • 46
Muju
  • 884
  • 20
  • 54
  • Possible duplicate of [how to add nil to nsmutablearray?](http://stackoverflow.com/questions/2057910/how-to-add-nil-to-nsmutablearray) – Puvanarajan Dec 09 '16 at 07:19
  • 1
    @Puvanarajan I have ask the question How to add in dynamic array that question is for static array.And my question is regarding to the count problem in cellforrowatindexpath. Please read the full question. – Muju Dec 09 '16 at 07:23
  • @Muju has this been resolved? – Joshua Dec 14 '16 at 08:43
  • @Joshua No this is not resolve. – Muju Dec 14 '16 at 09:15
  • @Muju what is devices? its seems that its a different thing from _devices how are you refreshing the table? based on your code its before you update _devices – Joshua Dec 14 '16 at 09:28
  • @Joshua devices is a NSMutableArray of core data. I am refreshing by using [Audittable reloadData]; – Muju Dec 14 '16 at 09:36
  • What is a dynamic resp. static array? Why do you store index paths into an managed object? The need of storing a null value into a collection is almost always a clear sign for doing something completely wrong. The whole idea sounds … eh … strange. – Amin Negm-Awad Dec 18 '16 at 05:09

6 Answers6

10

We cannot add nil directly inside a collection like NSMutableArray as it will raise an exception. If at all it is required to add nil inside collections like NSMutableArray, we can do so by using a singleton class NSNull.

For instance, we have a array of type NSMutableArray, we can add nil using NSNull as-

[array addObject:@"string"];
[array addObject:[NSNull null]];

... and so on...

The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).

Sanjay Mohnani
  • 5,947
  • 30
  • 46
  • By adding addObject my app get crash. Is there is any other way to add [NSNull null] class in NSMutableArray. – Muju Dec 09 '16 at 07:30
  • @Muju, are you using addObject: method on NSMutableArray? – Sanjay Mohnani Dec 09 '16 at 10:19
  • @sanjayMohanani Yes on NsMutableArray in cellforrowatindexpath. – Muju Dec 09 '16 at 10:24
  • `NSIndex Out of bound..`? Could you please be more specific? With the complete error? – VitorMM Dec 14 '16 at 12:36
  • 1
    @Muju: This is the correct answer, can you please post the code you are using to add an NSNull object to the NSMutableArray and also a stack trace of the error you are getting? I have a feeling you're not initialising the NSMutableArray object correctly. – Danny Bravo Dec 15 '16 at 09:48
5

First you can't add elemets in NSArray, you must use NSMutableArray instead. Second thing you can not add nil in your NSMutableArray.

So, you should add empty string instead of nil something like,

NSMutableArray *arr = [[NSMutableArray alloc]init];

[arr addObject:@""];

or you can add NSNull Object like,

[arr addObject:[NSNull null]];

And you can check that string is empty or not when want to display in UI something like(if added empty string),

NSString *tempStr = [arr objectAtIndex:0];

if (tempStr.length > 0) {

    NSLog(@"string is not empty.");
}
else{

    NSLog(@"Sring is empty");
}
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • your code show error [__NSArrayI addObject:]: unrecognized selector sent to instance – Muju Dec 09 '16 at 09:05
  • 1
    @Muju you declared a NSArray instead of a NSMutableArray, otherwise the error wouldn't say `__NSArrayI ` – VitorMM Dec 14 '16 at 12:32
2

Ok I got your problem. You actually wants to merge data from 3 different array into one single cell, but the problem is your array count is different for each array. Yes you can do this but you have to change the way of coding.

Lets assume you have 3 arrays a1, a2 and a3, with counts:

  • a1.count = 5,
  • a2.count = 8,
  • a3.count = 10

Here I'm assuming a1 is array of NSString while a2 & a3 are arrays with numbers (NSIntegers)

Now create one simple class inheriting from NSObject. We call it as AuditTableViewDao. It is simple Data Access Object

#import <UIKit/UIKit.h>

@interface AuditTableViewDao : NSObject

@property (nonatomic) NSString *checkForWhat;
@property (nonatomic) NSString *methodMeasures;
@property (nonatomic) NSString *visualInspections;

- (instancetype)initWithCheckForWhat:(NSString *)checkForWhat methodMeasures:(NSString *)methodMeasures visualInspections:(NSString *)visualInspections;

@end

Then in .m file of this AuditTableViewDao.m, write implementation to initialize.

Then in your ViewComtroller.m file, create one property

@property (nonatomic) NSMutableArray *arrayAuditTableViews;

in viewDidLod, write

self.arrayAuditTableViews = [[NSMutableArray alloc] init];
for (NSInteger index=0; index < a3.count; index++) {
        AuditTableViewDao *auditTableViewDao = nil;
        if (index < a1.count) {
            auditTableViewDao = [[AuditTableViewDao alloc] initWithCheckForWhat:((NSString *)[a1 objectAtIndex:index]) methodMeasures:[NSString stringWithFormat:@"%d", [a2 objectAtIndex:index]] visualInspections:[NSString stringWithFormat:@"%d", [a3 objectAtIndex:index]]];
        }
        else if (index < a2.count) {
            auditTableViewDao = [[AuditTableViewDao alloc] initWithCheckForWhat:"" methodMeasures:[NSString stringWithFormat:@"%d", [a2 objectAtIndex:index]] visualInspections:[NSString stringWithFormat:@"%d", [a3 objectAtIndex:index]]];
        }
        else if (index < a3.count) {
            auditTableViewDao = [[AuditTableViewDao alloc] initWithCheckForWhat:"" methodMeasures:"" visualInspections:[NSString stringWithFormat:@"%d", [a3 objectAtIndex:index]]];
        }
        [self.arrayAuditTableViews addObject:auditTableViewDao];
    }

And finally in your cellForRowAtIndexPath, Use object of arrayAuditTableViews at perticular index path.

appleBoy21
  • 632
  • 8
  • 23
  • I dont want to merge. I got problem in count of array – Muju Dec 09 '16 at 09:10
  • Yes I got that problem is with different counts of array. So I am suggesting you to create a new array with AuditTableViewDao instances. Where you can easily put all empty strings. Later it will also easy for you to manipulate – appleBoy21 Dec 09 '16 at 09:13
  • what I am suggesting is to combine the data required in your one cell into one object from your 3 different arrays – appleBoy21 Dec 09 '16 at 09:15
2

You need to add null in your array like this:

[yourArray addObject:[NSNull null]];
Sarabjit Singh
  • 1,814
  • 1
  • 17
  • 28
2

Add null

[array addObject:[NSNull null]];

nil is not an object that you can add to an array: An array cannot contain nil. This is why addObject:nil crashes.

Darshan
  • 2,272
  • 3
  • 31
  • 43
1

Don't need to save the index Path in core data and don't need to add Null or nill value.

Just alloc NSMutableArray in viewDidLoad method

NSMutableArray *_selectedIndexPath = [[NSMutableArray alloc] init];

Then in didSelectRowatIndexPath addObject in array like this

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

        if (![_selectedIndexPath containsObject:indexPath]) { // Check if array does not contain selecting cell, add this cell to array
            [_selectedIndexPath addObject:indexPath];
            [tableView reloadData];
        }
    }

And then in Cellforrowatindexpath

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
       if ([_selectedIndexPath containsObject:indexPath]) {
                cell.backgroundColor=[UIColor greenColor];
            }
            else
            {
                cell.backgroundColor=[UIColor whiteColor];
            }
}

And you can change your colour without using core data and null or nil value.

Muju
  • 884
  • 20
  • 54