0

I trying fill array from existing filled array but sometimes get this error:

*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[4830]

Exception caused by this code line:

 NSArray *result = [NSArray arrayWithArray:self.testerLog];

testerLog is NSMutableArray and I use it for collect logs from App. tester logs filled next way:

[self.testerLog addObject:[NSString stringWithFormat:@"%@: %@ \n", [NSDate date], logRecord]];

How it could happens? No exception when I add object to testerLog and fail when trying fill array from this filled array?

Edit: About initializing testerLog. Here is code of testerLog method:

- (NSMutableArray *)testerLog {
    if (!_testerLog) {
        _testerLog = [NSMutableArray array];
    }

    return _testerLog;
}

So I think it should be not nil.

UPDATE: I forget to say that method that add NSString to testerLog may called from several threads;

2
  • 1
    Is self.testerLog nil? Did you ever initialize it? Commented Jan 18, 2013 at 7:11
  • @KurtRevis, added initializing method in main post. Also error says that cannot insert 4830 object, because it is nil. testerLog should be not nil. This is why it so strange for me Commented Jan 18, 2013 at 9:21

2 Answers 2

1

The getter you posted is not thread safe. To get an equivalent thread safe getter, use the following code instead.

-(NSMutableArray *)testerLog {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        // If you're not using ARC you most definitely want to retain the array!
        // _testerLog = [[NSMutableArray array] retain]; 

        // If you're using ARC you should just assign
        _testerLog = [NSMutableArray array];
    });

    return _testerLog;
}

The dispatch_once call makes sure that whatever code you put into it, it will only be executed once during you app's lifetime (in a thread-safe manner). The static onceToken is what identifies the particular block. In your particular case this is useful because it guarantees that the array is instantiated only once no matter how many threads execute this getter.

NON-ARC ONLY: The retain is because you want the array to survive beyond this method's execution (again, ONLY if you are not using ARC).

Also, if you're not expecting to see a nil value somewhere because it means there was some logic error: use assertions. The following is an example of how to use them:

assert(self.testerLog != nil);
NSArray *result = [NSArray arrayWithArray:self.testerLog];
Sign up to request clarification or add additional context in comments.

3 Comments

thanks. Good suggestion about assertion. About problem: what you think about using @synchronization keyword for adding logs? Something like: @synchronized(self.testerLog) { [self.testerLog addObject:logString]; }
Also I think problem not in initializing of tester log array. Exception is "attempt to insert nil object from objects[4830]" so it seems that one of objects in array is nil. Become nil. How could this happen?
@Alexey - If you are writing and reading strings to and from the same array in multiple threads, you should make sure that each time you write to it or read from it, you're being thread safe. You can indeed try adding @synchronized(self.testerLog) {<your_read_or_write_code>} around such code to try this out.
0

Make sure you properly initialized your testerLog array. It's nil and that's causing your problem!

addObject may not be throwing an error because you're trying to add a valid NSString to your testerLog array. Try doing an NSLog on self.testerLog immediately after the line where you add the object, and see that it's printing the testerLog array correctly as you would expect.

1 Comment

Added initializing method in main post. Also [self.testerLog addObject:] may called from several thread. May it caused error?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.