I am trying to copy NSMutableArray to another but it does not show me anything at the UITableView:
NSMutableArray *objectsToAdd= [[NSMutableArray alloc] initWithObjects:#"one",#"two"];
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:objectsToAdd,nil];
NSMutableArray *list = [[NSMutableArray alloc] init];
[self.list addObjectsFromArray:myArray];
Nothing show up! What is wrong?
It crashes my app because I do not have nil at my NSMutableArray how can I add nil to it? addobject:nil does not work it crashes the app:
static NSString * DisclosureButtonCellIdentifier =
#"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
DisclosureButtonCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: DisclosureButtonCellIdentifier]
autorelease];
}
NSUInteger row = [indexPath row];
NSString *rowString =nil;
rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
[rowString release];
return cell;
Your initial call to alloc an NSMutableArray will most likely crash, since you don't have a nil terminator in your argument list.
Also, you have a local variable, list, and a property, list. Make sure you're instantiating what you think you are. You might need to do this:
NSMutableArray *objectsToAdd= [[NSMutableArray alloc] initWithObjects:#"one",#"two", nil];
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:objectsToAdd,nil];
self.list = [[NSMutableArray alloc] init];
[self.list addObjectsFromArray:myArray];
This might help you:
NSMutableArray *result = [NSMutableArray arrayWithArray:array];
or
NSMutableArray *result = [array mutableCopy]; //recommended
There are a few problems... One problem is that you're using 'initWithObjects' and adding the previous array. This seems like unwanted behaviour since you most likely want to add the strings #"one" and #"two" to the array. You most likely intended to use initWithArray or addObjectsFromArray. (Doing it the way you did, will add the NSMutableArray (not its objects) to the list)
The second problem, when you use initWithObjects, you need to list each of the objects and then terminate the list with a nil value. (docs) In other words, you need to use...
NSMutableArray *objectsToAdd = [[NSMutableArray alloc] initWithObjects:#"One", #"Two", nil];
The problem might be that the local declaration of listin line 4 conflicts with the property.
Related
I want to replace an array object in NSMutableArray obect.
I am getting oldArray from _alertsArray and changing its value and want to replace oldArray with newArray . but there is no effect!!
NSArray *oldArray = (NSArray *)[_alertsArray objectAtIndex:[indexPath row]];
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray copyItems:YES];
[newArray replaceObjectAtIndex:3 withObject:#"YES"];
[_alertsArray replaceObjectAtIndex:[indexPath row] withObject:newArray];
NSMutableArray *newArray = [_alertsArray mutableCopy];
[newArray replaceObjectAtIndex:3 withObject:#"YES"];
_alertsArray = newArray;
I am unable to access my NSMutableArray in didSelectRowAtIndexPath although i am able to access it in cellForRowAtIndexPath.
Here is my code :-
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"drinks" ofType:#"plist"];
self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(#"%#", self.drinkArray);
[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSLog(#"I am inside cellForRowAtIndexPath");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dict objectForKey:#"name"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[dict release];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DrinkDetails *detailViewController = [[DrinkDetails alloc] initWithNibName:#"DrinkDetails" bundle:nil];
// ...
// Pass the selected object to the new view controller.
//detailViewController.drink = [self.drinkArray objectAtIndex:indexPath.row];
NSLog(#"%#", self.drinkArray);
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Sometime NSLog prints some stupid output and sometime it gives me an error "EXC_BAD_ACCESS".
Please take a look and check what is wrong with my code.
Any help would be appreciated.
Thanks.
You have one (really two) issues, but the main one is in your -cellForRowAtIndexPath: method:
[dict release];
Get rid of this line and it should work just fine.
The reason why this fixes your issue is because -objectAtIndex: simply returns a pointer to the requested object in memory, therefore you do not (and should not) send the -release message to that object because the NSArray obtained ownership of the object when it was inserted. Sending -release to this object reference effectively deallocates the object in memory and now this indice in the NSArray is pointing to garbage memory. BAD BAD BAD
The other issue is that you have a memory leak here:
self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
You are sending the -retain message to an object reference that you already have ownership of by way of sending -alloc. (This of course assumes that your #property has the retain setter modifier)
To fix this issue, simply send the -autorelease message to this instance:
self.drinkArray = [[[NSMutableArray alloc] initWithContentsOfFile:path] autorelease];
Don't release an object unless it was created with alloc or obtained with a method beginning with new or copy or explicitly retain'ed. (NARC)
In this case:
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
was not returned retained so you do not have ownership and should not release it.
By the same token:
self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
is alloc'ed so it needs to be released or obtained with a convince method that will return an autoreleased object:
self.drinkArray = [NSMutableArray arrayWithContentsOfFile:path];
You shouldn't [dict release]in cellForRowAtIndexPath. objectAtIndex does not retain it, so it may be sweeped out of your array when you release it.
I have been trying for hours to figure this out. I have some JSON from a NSURLConnection. This is working fine and I have parsed it into an array. But I can't seem to get the array out of the connectionDidFinishLoading method. I an am getting (null) in the UITableViewCell method. I am assuming this is a scope of retain issue, but I am so new to ObjC I am not sure what to do. Any help would be greatly appreciated.
Cheers.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
SBJSON *json = [[SBJSON alloc] init];
NSDictionary *results = [json objectWithString:responseString];
self.dataArray = [results objectForKey:#"data"];
NSMutableArray *tableArray = [[NSMutableArray alloc] initWithObjects:nil];
for (NSString *element in dataArray) {
//NSLog(#"%#", [element objectForKey:#"name"]);
NSString *tmpString = [[NSString alloc] initWithString:[element objectForKey:#"name"]];
[tableArray addObject:tmpString];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
//cell.textLabel.text = [self.tableView objectAtIndex:indexPath.row];
cell.textLabel.text = [self.tableArray objectAtIndex:indexPath.row];
NSLog(#"%#", tableArray);
return cell;
}
Solution:
After taking kubi and st3fan's advice with self.tableArray I found I had to reload the tableView with [self.tableView reloadData];
Get rid of the [connection release] in the 2nd line. The connection object comes in autoreleased, so this could cause crashes.
It looks like you've got a property named tableArray? If so, you're redeclaring the name in this method (you should have gotten a compiler warning).
On second thought, here's how the 2nd 1/2 of the method should look:
NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithObjects:nil];
for (NSString *element in dataArray) {
[tmpArray addObject:[element objectForKey:#"name"]];
}
self.tableArray = tmpArray;
[tmpArray release];
In connectionDidFinishLoading: you use declare tableArray as a local variable. Therefore it will never be assigned to self.tableArray.
I had the same problem and I resolved it reloading the table.
I inserted this line at the end of connectionDidFinishLoading function
[self.tableView reloadData];
and it works.
Okay, so I have an app that I'm trying to get to populate a UITableView with the contents of a plist file. I haven't been able to find anyone else having problems doing this and how they fixed it so I'm probably just an idiot but I need to know how all the same!
I'm sure the error is somewhere in my viewDidLoad section or my tableview section...but maybe someone else can give me a better idea.
-(void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"datam" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
self.listData = array;
[array release];
[super viewDidLoad];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
I think [super viewDidLoad] should be foremost in the viewDidLoad method.
NSString *path = [[NSBundle mainBundle] pathForResource:#"datam" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:path];
This seems a little odd; is your file named "datam.plist"?
Try using some NSLogs() throughout your code to see what the status of your array is at any given time:
NSLog(#"%# has %i elements",ARRAY_OBJECT,[ARRAY_OBJECT count]);
Check the GDB output in XCode while the application runs to see if the results match what you expect.
self.listData = array; [array release];
Try this instead:
self.listData = [array copy]; [array release];
NSArray objects are pointers; when you set self.listData = array, you really tell anything looking for listData to look in the memory address originally occupied by array. When you release array, it vacates that memory address, thus making the pointer point to nothing.
I defined an array for tableView's listData.
NSArray *array = [[NSArray alloc] initWithObjects:#"Sleep", #"Bashful", #"Happy", nil];
self.listData = array;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
cell.text = [listData objectAtIndex:row];
Now I want to add more data to the tableview. How to connect another data to it so when I click a button the array will be #"A", "B", "C", "D", nil?
The easiest way to do this is to use the NSMutableArray with insertObjetcAtIndex or addObject:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"Sleep", #"Bashful", #"Happy", nil];
[array insertObject:#"XYZ" atIndex:3];
[array addObject:#"ABC"];