Anyone got any ideas why this Table View code is crashing?
This, in my viewDidLoad:
itemArray = [NSArray arrayWithObjects:#"1", #"2", #"3", #"4", #"5", #"6", #"7", nil];
Then, this in my cellForRowAtIndexPath method:
cell.textLabel.text = [NSString stringWithFormat:#"Item (%#)", [itemArray objectAtIndex:indexPath.row]];
When I scroll down (i.e. so that object 1 goes off screen) then scroll back to try and see object 1, it crashes at this previous line.
It's fine if I replace the offending line with something like this:
cell.textLabel.text = #"test";
UPDATE: Answer was that the array was not being retained.
This line fixed the problem:
itemArray = [[NSArray arrayWithObjects:#"1", #"2", #"3", #"4", #"5", #"6", #"7", nil] retain];
OR
itemArray = [[NSArray alloc] initWithObjects:#"1", #"2", #"3", #"4", #"5", #"6", #"7", nil];
Your itemArray seems not to be retained. arrayWithObjects: returns an autoreleased object. You need to retain or copy it, or use the syntactic sugar of a retaining property.
Related
I am fresher to iOS. In my application i have 3 mutable arrays with objects like
NSMutableArray *MuteItem = [NSMutableArray alloc]initWithObjects:#"a", #"b", #"b", #"c", #"c", #"c", nil]];
NSMutableArray *MuteQuantity = [NSMutableArray alloc]initWithObjects:#"1", #"1", #"1", #"1", #"1", #"1", nil]];
NSMutableArray *MutePrice = [NSMutableArray alloc]initWithObjects:#"4", #"3", #"3", #"6", #"6", #"6", nil]];
Now i need to print that 3 mutable arrays values with counting the same item's quantity and calculate the price also like objects
MuteItem = { a, b, c }
MuteQuantity = { 1, 2, 3 } // counting of same item's quantity like {1, 1+1, 1+1+1}
MutePrice = { 4, 6, 18 } // here addition of same item's prices like {4, 3+3, 6+6+6}
So anybody, would you please help me in this problem. Thanks in advance.
This code will do exactly as you requested, and will even handle any keys in MuteItem, and will generate three new arrays with the aggregate information from each of the three original arrays.
NSMutableArray* muteItem = [[NSMutableArray alloc] initWithObjects: #"a", #"b", #"b", #"c", #"c", #"c", nil];
NSMutableArray* muteQuantity = [[NSMutableArray alloc] initWithObjects: #"1", #"1", #"1", #"1", #"1", #"1", nil];
NSMutableArray* mutePrice = [[NSMutableArray alloc] initWithObjects: #"4", #"3", #"3", #"6", #"6", #"6", nil];
NSMutableArray* setItem = [NSMutableArray array];
NSMutableArray* setQuantity = [NSMutableArray array];
NSMutableArray* setPrice = [NSMutableArray array];
NSSet* itemSet = [NSSet setWithArray: muteItem];
for (NSString* key in itemSet) {
NSIndexSet* indices = [muteItem indexesOfObjectsPassingTest: ^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [obj isEqualToString: key];
}];
__block NSInteger totalQuantity = 0;
__block NSInteger totalPrice = 0;
[indices enumerateIndexesUsingBlock: ^void(NSUInteger idx, BOOL *stop) {
totalQuantity += [[muteQuantity objectAtIndex: idx] integerValue];
totalPrice += [[mutePrice objectAtIndex: idx] integerValue];
}];
[setItem addObject: key];
[setQuantity addObject: [NSNumber numberWithInteger: totalQuantity]];
[setPrice addObject: [NSNumber numberWithInteger: totalPrice]];
}
NOTE: This code assumes you are using ARC. Also, in your original code you forgot to nil terminate your array constructors.
EDIT: I notice that your prices are integers, you may want to change them to floats if your currency uses decimal fractions. This would require changing the definition of totalPrice to float and you would want to change the end of the totalPrice += line from integerValue to floatValue.
EDIT2: Renamed all variables that started with a capital letter as this violates standard naming convention. Only class names should begin with a capital letter, variables should always begin with lowercase, or an _ for instance variables. :)
Is the following legal in Objective-c with ARC enabled?
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
I thought it should be. However, in this situation it gives me EXEC_BAD_ACCESS on the forth line:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
addObject copies the pointer right? So if I allocate a new segment of memory to smallArray to point to, what is wrong with that?
However this code segment does not crash:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] init];
[smallArray addObject:#"4"];
[smallArray addObject:#"5"];
What's going on here?
Try this:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
The second object must be #"5", not just "5".
I guess this is because you forgot the # in the string "5". it should be:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", #"5", nil];
I am not sure what I am doing wrong here? I have tried various combinations to try and copy an array into variable mmm. I am trying to learn how to create a 2D array and then run a loop to place init_array into 10 columns.
// NSMutableArray *mmm = [NSMutableArray arrayWithCapacity: 20];
NSMutableArray *kkk = [NSMutableArray arrayWithObjects: #"a", #"b", #"cat", #"dog", nil];
NSMutableArray *mmm; //= [NSMutableArray arrayWithObjects: #"1", #"2", #"3", #"4", nil];
[mmm arrayByAddingObjectsFromArray:kkk];
NSLog(#"Working: %#",[mmm objectAtIndex:3]);
thanks...
so this works from the given answer:
NSMutableArray *mmm = [NSMutableArray arrayWithCapacity: 20];
NSMutableArray *kkk = [NSMutableArray arrayWithObjects: #"a", #"b", #"cat", #"dog", nil];
[mmm addObjectsFromArray:kkk];
NSLog(#"Working: %#",[mmm objectAtIndex:3]);
arrayByAddingObjectsFromArray: returns a new (autoreleased) NSArray object. What you want is addObjectsFromArray:.
arrayByAddingObjectsFromArray: returns a new NSArray that includes the objects in the receiver followed by the objects in the argument. The code you posted there, with mmm unset, will probably just crash since mmm doesn't point to an NSArray object. If you had assigned an array to mmm, then it would return (#"1", #"2", #"3", #"4", #"a", #"b", #"cat", #"dog") — but you don't assign the result to any variable, so it just goes nowhere. You'd have to do something like NSArray *yetAnotherArray = [mmm arrayByAddingObjectsFromArray:kkk].
If you have an NSMutableArray and you want to add objects from another array, use addObjectsFromArray:.
I can not figure out why this code is bad. I thought it was ok to use static strings in dictionaryWithObjectsAndKeys however it fails at runtime with a EXC_BAD_ACCESS. I used the debugger to identify that it is in fact failing at the definition line. It never outputs "Made it here".
- (NSString *)polyName:(NSUInteger)vertices {
NSLog(#"looking for polyName with %d vertices.", vertices);
NSDictionary *polNameDict = [NSDictionary dictionaryWithObjectsAndKeys:
#"triangle", #"3",
#"square", #"4",
#"pentagon","5",
#"Hexagon", #"6",
#"Heptagon", #"7",
#"Octagon", #"8",
#"Nonagon", #"9",
#"Decagon", #"10",
#"Hendecagon", #"11",
#"Dodecagon", #"12",
nil];
NSLog(#"Made it here");
NSString *key = [NSString stringWithFormat: #"%d", vertices];
NSString *polName = [polNameDict objectForKey:key];
return (polName);
// Memory management: No need to release polNameDict, key, polName because they use
// convenience functions
}
The problem is here:
#"pentagon","5"
It expects an object (NSString) but instead there's a regular string.
Change it to:
#"pentagon", #"5"
What line does the EXC_BAD_ACCESS occur on? Utilize breakpoints and let us know.
For now, if I were you, I'd do something like this:
NSDictionary *polNameDict = [[NSDictionary alloc] initWithObjectsAndKeys:
#"triangle", #"3",
#"square", #"4",
#"pentagon",#"5",
#"Hexagon", #"6",
#"Heptagon", #"7",
#"Octagon", #"8",
#"Nonagon", #"9",
#"Decagon", #"10",
#"Hendecagon", #"11",
#"Dodecagon", #"12",
nil];
instead of how you have it now.
Can each index of array hold the NSDictionary?
Thank You.
Yes, the value of an NSArray can resolve to an object identifier for an NSDictionary. However, the array doesn't "hold" the NSDictionary, nor can the index of an NSArray be an NSDictionary. An index from an Array is always an integer value.
An NSArray can hold any type of object, so yes, putting an NSDictionary in an NSArray works just fine.
You sure can, here is an example:
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:
#"value1", #"key1", #"value2", #"key2", nil];
NSDictionary *dict2 = [[NSDictionary alloc] initWithObjectsAndKeys:
#"Billy", #"Goat", #"Rover", #"Dog", nil];
NSArray *arrayWithDictionaries = [[NSArray alloc] initWithObjects:
dict1, dict2, nil];
[dict1 release];
[dict2 release];