I am trying to fetch data from core data, it works fine. But when I try to fill a Table Cell then it gives me warning at the following line
cell.textLabel.text = [fetchedObjects objectAtIndex:indexPath.row];
Warning : passing argument 1 of 'objectsAtIndexes:' makes pointer from integer without a cast.
fetchedObjects is an NSArray object declared in header file. Kindly guide me where I am doing wrong. I can provide whole method for more understanding.
Regards.
EDIT
Here is my complete method code:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"] autorelease];
cell.textLabel.text = [fetchedObjects objectAtIndex:indexPath.row];
return cell;
}
Your posted code says you're calling objectAtIndex, which does indeed take an integer parameter. However, your error says you're using objectAtIndexes, which takes a pointer to an NSIndexSet. As indexPath.row is not an NSIndexSet pointer, you're getting that warning (saying that you're trying to use a raw integer as a pointer).
Check your actual code. Almost certainly, you're using objectAtIndexes by mistake.
Related
Currently I fill a UITableView using this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CharNameCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
MyObject *obj = (MyObject*)[self.characters objectAtIndex:indexPath.row];
cell.textLabel.text = obj.name;
return cell;
}
But what could one do if you had two different arrays from two different types and you wanted to display a property from each in the cells?
Pseudocode:
MyObject1
MyObject2
cellTextLabel.text = Myobject1.name;
cellTextLabel.text = MyObject2.name;
Assuming that each object has a name property. I know my syntax above isn't correct, but I think you should get the drift.
I would suggest then that you store all of your objects in an NSMutableArray. This will be your data model. Then you can just iterate through the array to display the data in the UITableView. If need be, use introspection to find out what kind of class your object is.
id currentObject = [myArray objectAtIndex:indexPath.row];
if ([currentObject isKindOfClass:[MyObject1 class]]){
//set properties or do stuff with MyObject1
}else if ([currentObject isKindOfClass:[MyObject2 class]]){
//do stuff with Object2
}
This is just one suggestion. There are many ways to do this, but it will all depend on your app and what kind of persistence you are using, etc. Hope this helps.
I'm having a problem adding an item to my tableView.
I used to initialize an empty tableView at the start of my App and get it filled with scanned items every time the tableView reappears and there is an item in my variable.
Initialization of the tableView:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:nil];
self.listArray = array;
TableView Data Source:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.listArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
return #"Eingescannte Artikel:";
else
return nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"testCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
NSUInteger row = [indexPath row];
cell.textLabel.text = [listArray objectAtIndex:row];//[NSString stringWithFormat:#"Das ist Zeile %i", indexPath.row];
return cell;
}
(Not the whole thing but the ones I changed)
As you may have seen I use an NSMutableArray to add items to my tableView.
So if an item ist scanned I'm adding it to my array like this:
[listArray insertObject:sharedGS.strEAN atIndex:0]; //using a shared Instance where I implemented my variable.
I also tried to use an variable to extend my Index every time a new Item is added, but it won't work both ways.
I'm quite new to programming so an not-too-hard-to-understand-answer would be quite nice ;)
If there's any information missing, feel free to ask.
/edit: Trying to specify my question: The data from the variable is written in a TableViewCell, but if I scan another one the other one is just being replaced. Not sure if it's a problem with my array or my tableView...
/edit No.2: Found out(thanks to fzwo) that my array isn't working correctly. It just doesn't grow by an addObject: or insertObject:atIndex: command. But I just don't get why... :(
All I'm doing: [listArray addObject:sharedGS.strEAN]; not that much space for errors in one simple line. Maybe I'm just too stupid to recognize what I'm doing wrong:D
You state that your problem is "adding an item to my tableView" , since you are adding the object to your array i am guessing the problem is that you are not reloading the table or that it is missing the dataSource binding.
You have not actually asked any question (even if you added info to "specify your question") so a wild guess, after
[listArray insertObject:sharedGS.strEAN atIndex:0];
put
[yourTableView reloadData];
Are you intentionally adding new items to the top of the table ? otherwise you could do
[listArray addObject:sharedGS.strEAN]; to add new items to the bottom
Otherwise it's worth noting that you are misusing dequeueReusableCellWithIdentifier, look at the example below for proper usage:
// Try to retrieve from the table view a now-unused cell with the given identifier
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
// If no cell is available, create a new one using the given identifier
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
Following the documentation on custom cells from a NIB (the Dynamic option), I have this method. (The view itself is not a UITableViewController, but it's hooked up properly.)
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"ReusableCell";
UITableViewCell *cell = (LoadGameCell *)
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[NSBundle mainBundle]
loadNibNamed:#"LoadGameCell" owner:self options:nil];
cell = loadGameCell;
self.loadGameCell = nil;
}
/*
cell setup
*/
return cell;
}
The first line in the if statement is the bit I'm having trouble with.
Incompatible pointer types assigning to 'UITableViewCell *' from 'NSArray *'
Incompatible Objective-C types assigning 'struct NSArray *',
expected 'struct UITableViewCell *'
No errors/crashes running the app with these warnings, but I'd rather not ignore/suppress them. It'll hurt a whole lot more later on.
If it isn't a direct result of the warnings above, there's another problem. I can't get the method to take views, only labels. (That is, I can customize a label, but not the image view it's sitting next to.)
As the documentation will tell you, loadNibNamed:owner:options: returns an array. To access the cell in the NIB (assuming it is the only root-level object in the NIB), call objectAtIndex:0 on the result of loadNibNamed:owner:options.
So basically I am trying to create instances of the class below every time I received a valid response from a web request and then store those instances in an array so I can access their data later. Then, I try to populate a table view with specific fields from the instance(s) that are stored in the array. I've been having some issues since I am very familiar with C++ and do this sort of thing with vectors and then just access based off of the index I need, but this has had me pulling my hair out! Thanks, code is below:
eventDetails.h:
#interface eventDetails : NSObject {
NSString *eventName, *eventID;
}
-(void) setEventID : (NSString *) ID;
-(void) setEventName: (NSString *) name;
-(NSString *) getEventName;
-(NSString *) getEventID;
and also note that
NSMutableArray *events
is declared in my .h file and
events = [[NSMutableArray alloc] init];
has been called in the viewDidLoad
I then dynamically create instances as a response is received from an web request and add them to an array:
if ([elementName isEqualToString:#"id"])
{
NSLog(#"at beginning of event, length is %i", [events count]);
temp = [[eventDetails alloc] init];
[temp setEventID:[NSMutableString stringWithString:soapResults]];
[soapResults setString:#""];
elementFound = FALSE;
}
if ([elementName isEqualToString:#"name"])
{
[temp setEventName:[NSMutableString stringWithString:soapResults]];
[events addObject:temp];
[soapResults setString:#""];
elementFound = FALSE;
//[temp release];
}
After everything is all said and done, I created a little test function to ensure the data was set correctly:
-(void) test{
for (eventDetails *s in events){
NSLog(#"Entry ID: %# with name %#", [s getEventID], [s getEventName]);
}
}
and I get the following (correct) output:
2011-04-09 18:53:24.624 Validator[90982:207] Entry ID: 701 with name iPhone Test Event
2011-04-09 18:53:24.625 Validator[90982:207] Entry ID: 784 with name Another iPhone Test Event
2011-04-09 18:53:24.626 Validator[90982:207] Entry ID: 839 with name third iphone
I then try to refresh the table view, and have it pull in data from the instances in the array:
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
//---try to get a reusable cell---
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//---create new cell if no reusable cell is available---
if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
//---set the text to display for the cell---
eventDetails *cellDetails = [[eventDetails alloc] init];
NSInteger row = [indexPath row];
cellDetails = [[self events] objectAtIndex:row];
NSString *cellValue = [cellDetails getEventName];
NSLog(#"Event is: %#", cellValue);
cell.textLabel.text = cellValue;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
But every time the program gets to this part, it crashed which a EXC_BAD_ACCESS where I say:
cell.textLabel.text = cellValue;
Thanks for your help. I think I might be doing something wrong with how I declare the instances of the eventDetails class, but I am not sure since it is working correctly as far as storing that data. If you need any more code, I have the missing sections.
There are too many omitted details in the code you posted to know for sure, but my guess would be the eventName isn't retained, and is deallocated sometime before you attempt to use it.
Check your setEventName: implementation; it would need to send either retain or copy to the name argument to ensure that the string won't be deallocated before you're done using it. However, the situation is more complex than that if you want to avoid memory leaks, so you if you haven't done so already, I'd recommend reading up on memory management, in particular, Apple's excellent Memory Management Programming Guide. (Note: I've given up posting links since Apple keeps changing them).
A side note: don't prefix the names of accessor methods with the word get; that would be fine in Java or C++, but this is Objective-C. Your accessors should look like this:
- (NSString *)eventName;
- (NSString *)eventID;
There's no guarantee that Foundation mechanisms that rely on introspection will work correctly with accessors that don't follow the documented naming conventions, so that's another thing to read up on. :-)
I have a memory leak that displays UICachedDeviceWhiteColor. I'm not using UICachedDeviceWhiteColor anywhere and a search on it turns up people saying this is a bug in the iPhone-SDK. I found this blog entry:
http://piezoelectrics.blogspot.com/2009/02/uicacheddevicewhitecolor-leak-in-iphone.html
but I can't find
#import "NSAutoreleasePool.h"
I get an "error: NSAutoReleasePool.h: no such file or directory". Is there a fix for this memory leak or a correct way to allocate table cells from nibs?
Here's how I'm currently doing it:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"CellNameIdentifier"];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CellName" owner:self options:nil];
//cellName is IBOutlet to XIB's tablecell. I reference it several times in this calss
cell = cellName;
}
return cell;
}
I don't see an alloc here so why would there be a mem leak? Could this be a problem:
#property (nonatomic, retain) IBOutlet UITableViewCell *cellName;
Because of your property declaration, the sythesized setter for your cellName property will retain the object passed to it.
You should send a release message to cellName in your dealloc method.
Furthermore, there is no need to load the nib every time the cellView is requested. Either check if cellName != nil and return it or set the reuseIdentifier on the cellView so that it can be found by dequeueReusableCellWithIdentifier.
Actually, if you're using a NIB for your table view cell (not normally necessary unless you're doing something really custom) you will have to load it each time you didn't get a hit on the reusable table view cell. I think the following code looks a bit cleaner:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyID"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CellName"
owner:self options:nil];
cell = [nib objectAtIndex:1];
}
The objectAtIndex:1 trick works if the cell is the first object in the NIB (the zero object is the file owner).
Some notes for doing table view cells:
Don't retain your cell objects either implicitly by assigning to a property or manually. This will make the the reusable table cell functionality not work properly since it can't free the cell memory.
Don't forget to set the cell reuse identifier in interface builder since you can't do it in code if you're using a NIB.
Always make sure the cell is autoreleased. Either do it manually, or ensure you're using a cocoa function that returns autoreleased memory (as the objectAtIndex: method does).