2

I am trying to assign objects in an NSMutableArray using this code

- (IBAction)variablePressed:(UIButton *)sender {
NSString *variable = [sender currentTitle];
if (!_variableToBePassedIntoTheDictionary) _variableToBePassedIntoTheDictionary = [[NSMutableArray alloc] init];
[_variableToBePassedIntoTheDictionary replaceObjectAtIndex:0 withObject:variable];}

but when I run this program the program breaks at the last line, since I have set the debugger to show warnings if a Exception is raised. Running the program without breakpoints, the program gives SIGARBT and crashes. I then assign these values to a dictionary which would be passed to the Model for further calculations.

- (IBAction)testVariableValues:(id)sender {
if (!_variablesAssignedInADictionary) _variablesAssignedInADictionary = [[NSMutableDictionary alloc] init];
[_variablesAssignedInADictionary setObject:_digitToBePassedIntoTheVariable forKey:_variableToBePassedIntoTheDictionary];
NSLog(@"%@", _variablesAssignedInADictionary);}

P.S. I am new in Objective C, can anybody please explain when do we use

@synthesize someProperty;

vs

@synthesize someProperty = _someProperty;

Thank You!

m.umar
  • 855
  • 4
  • 13
  • 23
  • SIGABRT most likely indicates you have a bogus pointer (not `nil`, but not addressing a valid object) somewhere. replaceObjectAtIndex is just the innocent bystander. – Hot Licks Jun 24 '12 at 14:07
  • Thank you for your help, but when I press any variable (in my case I have set three variable buttons x, y, z) shouldn't the value of 'variable' become what I have pressed? – m.umar Jun 24 '12 at 14:10
  • When I use addObject: it works perfectly fine but it does not work for my case since it does not replace the object and I need to replace the object every time the user assigns a new variable. I am basically building a programmable calculator. – m.umar Jun 24 '12 at 14:19

4 Answers4

2

The first time the method is called you create the NSMutableArray and then attempt to replace an object which is not there. The reference says:

- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject

The index of the object to be replaced. This value must not exceed the bounds of the array. Important Raises an NSRangeException if index is beyond the end of the array.

And 0 will exceed the bounds of an empty array.

Try this instead:

- (IBAction)variablePressed:(UIButton *)sender
{
    NSString *variable = [sender currentTitle];
    if (_variableToBePassedIntoTheDictionary == nil)
    {
        _variableToBePassedIntoTheDictionary = [[NSMutableArray alloc] init];
        [_variableToBePassedIntoTheDictionary addObject:variable];
    }
    else
    {
        [_variableToBePassedIntoTheDictionary replaceObjectAtIndex:0 withObject:variable];
    }
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
1

Taken from the docs :

The index of the object to be replaced. This value must not exceed the bounds of the array.

As I see from your code your array is initialized and there is no object at index 0. hence you try to replace an object at an index which is out of bounds as your array is empty.

giorashc
  • 13,691
  • 3
  • 35
  • 71
1

Very simple question:

You told it stops on an exception. Fair enough. What for an exception? Let me guess, an out of bounds exception? The exception tells you what's wrong in most cases.

replaceObjectAtIndex:0 : is there something at that index or not? Probably not.

1

In your code you test the condition:

if(!_variableToBePassedIntoTheDictionary)

and if the condition is true, that is the array is nil, then you alloc-init it. In the following statement:

[_variableToBePassedIntoTheDictionary replaceObjectAtIndex:0 withObject:variable];
, you try to replace the object at index 0 with variable. But in the case above, if you just alloc-init the array, it is empty and than you cannot replace the object at index 0 as not existing, and this raises an exception:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 0 beyond bounds for empty array'

So what you have to do is to change the last line as follows:

if([_variableToBePassedIntoTheDictionary count]==0) {
  [_variableToBePassedIntoTheDictionary addObject:variable]
} else {
[_variableToBePassedIntoTheDictionary replaceObjectAtIndex:0 withObject:variable]
}

As far as the second question about properties, consider that the role of synthesize is to create for you the setter/getter methods based on the attributes you assigned to the @property. In the new Objective-C you don't need to declare the ivar associated to the property (the ivar is the instance variable that represent the property) and the compiler by default assigns the ivar the name of the property. By using the

@synthesize someProperty = _someProperty

convention you specify that you want the ivar to be called _someProperty. The advantage of this approach with respect to the default one is that you cannot confuse accessing to a property using the setter/getter methods and the ivar directly, that is you cannot make possible mistakes like:

someProperty=value

but instead you must write:

_someProperty=value
or
self.someProperty=value

Anyway have a look at Obj-C documentation for this, it is quite exhaustive.

viggio24
  • 12,316
  • 5
  • 41
  • 34