Compare numbers in NSMutableArray with indexPath.row - ios

I have an NSMutableArray that gets edited quite often as a TableView is edited. What I want to do is run a check and see if rows in the TableView match up with any numbers in the NSMutableArray, and if they do, perform an action. So, in the TableView code I have:
if([thearray containsObject:indexPath.row] {
//perform action here
}
However I keep getting the error:
Incompatible integer to pointer conversion sending 'NSInteger' (aka 'int') to parameter of type 'id';
What am I doing wrong and how can I do this?

Use this code...
if([thearray containsObject:[NSNumber numberWithInt:indexPath.row]]) {
//perform action here
}

I think the best you can do here is check if the current count of the array is greater than indexPath.row the (since in theory there will be no gaps in the indexes). The method you are currently calling takes an object and tells you if it is a member of the array. There is also objectAtIndex:, but that raises an exception if the integer you pass is out of bounds.
if(thearray.count > indexPath.row) {
// array has at least indexPath.row + 1 items, so you can get objectAtIndex:indexPath.row
}

Related

Convert the original tableview to collectionview data cannot be passed

I want to replace the original tableview with collectionview, the code of the original tableview:
let selectedRow = MarketView.indexPathForSelectedRow!.row
I'm learning online to change to this code and I get an error:
let selectedRow = MarketView.indexPathsForSelectedItems!.first
The error shows:
Cannot convert value of type 'IndexPath?' to expected argument type 'Int'
This is the complete code as shown in the figure
I just learned to use collectionview, how should I modify it, thank you for your help
Unlike indexPathForSelectedRow which returns a single index path indexPathsForSelectedItems returns an array of index paths
And row is not first, the collection view equivalent of row – as the name of the API implies – is item, you have to write indexPathsForSelectedItems!.first!.item.
But it's not recommended to force unwrap the objects. A safer way is
guard let selectedRow = MarketView.indexPathsForSelectedItems?.first?.item else { return }

Unable to store sqlite3_last_insert_rowid into an array

I am using the following code to store "sqlite3_last_insert_rowid" into NSMutableArray,I am getting the rowid but nothing is stored in the array. It is giving me null.
NSUInteger rowIDNum=sqlite3_last_insert_rowid(myDatabase);
NSNumber *xWrapped = [NSNumber numberWithInt:rowIDNum];
[_rowID insertObject:xWrapped atIndex:0];
NSLog(#"row ID array %#",[_rowID objectAtIndex:0]);
Could you please tell me the correct way to store rowid into an array?
I suspect the array is not allocated, else you would get an NSRangeException if the array was allocated but empty (i.e. the first time you called that method).
From the NSMutableArray reference:
index
The index in the array at which to insert anObject. This value
must not be greater than the count of elements in the array.
Important: Raises an NSRangeException if index is greater than the
number of elements in the array.
You would normally allocate the array in the class init method or viewDidLoad method, depending on what the class is. Once you've allocated the array, use:
NSUInteger rowIDNum=sqlite3_last_insert_rowid(myDatabase);
[_rowID insertObject:#(rowIDNum)];

cannot insert into NSMutableArray due to indexvalue being out of bounds

I have a MutableArray on this view called array and the object in question is detailItem, which has a property of rank (int). On this view, there's a text field displaying the rank and I want to be able to move the detailItem up and down the MutableArray by changing the rank.
So, for example let's say the detailItem has a rank of 3, which is index value of 2. If I change this in the text field to 3, I want the array to adjust and move it down one place. However, as I type in the value of rankField (the text field), it crashes the app since it automatically updates the value before I'm done editing. So, if I click on the text field and write 23 (planing on deleting the 2) or just press delete (now the value is nil) the app crashes with an uncaught exception.
Here's the code:
- (IBAction)rankFIeldTextChanged:(id)sender {
QueueMember *member = self.detailItem;
[self.array removeObjectAtIndex:self.detailItem.rank];
if (0<= [self.rankField.text intValue]<= self.array.count) {
[self.array insertObject:member atIndex:[self.rankField.text intValue]-1];
}
}
The if condition of making the text value in-between the array size and 0 seems to have no effect.
btw this is all in the detailsViewController which is connected to the main view controller via push segue. does it make more sense(or more better coding) to just set the new rank value in details and actually make the array changes in the mainviewcontroller.m?
The problem is that you are trying to do two boolean statements at once (which doesn't work). Change your if statement to something like:
if (0< [self.rankField.text intValue] && [self.rankField.text intValue] < self.array.count) {
//Insert your object here
}
else
{
//Add object here
}
Your current setup check to see if 0<= [self.rankField.text intValue], which will return true for all values greater than or equal to 0. Then it checks the result of that (YES:1, NO:0) if it's less than or equal to your array count. That will always return true if your array has anything in it. So basically your check will always return true.
Since it always returns true I could check for array object number 1000, your if statement says go for it, then I check and the array says "No way in heck!" and crashes your app.
EDIT: Updated my code snippet to take into account your array insertion line.
I'd just do this
- (IBAction)rankFIeldTextChanged:(id)sender {
QueueMember *member = self.detailItem;
[self.array removeObjectAtIndex:self.detailItem.rank];
if ((0<= [self.rankField.text intValue])&&([self.rankField.text intValue]<= self.array.count)) {
if (self.array.count >([self.rankField.text intValue]-1)){
[self.array insertObject:member atIndex:[self.rankField.text intValue]-1];
}
}
}
you are probably trying to insert at an index greater than the count of the array.

Objective C - differentiate between nil and 'no value'

im building a chart view and I'm giving it a datasource to which it can ask for a Y value that corresponds to a given X index. In some cases, there is no Y value for a given X index. I can't send nil in this circumstance, as 0 may be a perfectly valid Y value. What is the best way in objective C to communicate that there is No Value at all?
It seems to me that you're sending the data between the model and the view using some sort of object, perhaps NSNumber, that's holding a value, and you are retrieving the value by sending it a message, and you know that if the object is nil, the message send will return 0.
That's correct. In this case, simply check if the object is nil, and proceed accordingly:
- (void)plotValue:(NSNumber *)number
{
if (number == nil) {
// no value
} else {
// Value may be 0, but you can now safely plot it.
}
}
Don't use primitives in your data source, instead use NSNumber. Then you can differentiate between nil and an NSNumber storing the value 0.
nil is not 0. They are different.
If you are using NSNumber, then nil is clearly disjoint from the set of NSNumber.
If you are using int, then you can't use nil.
If you don't want to use an object (NSNumber), you can return a negative number (if possible) or the maximum/minimum integer that is unlikely to be returned by the datasource.
I'm assuming you're talking about some scalar like an NSInteger or something. If literally any integer is valid for the Y value, then there is no way to do this. However, most likely there is some practical range, so you can just choose some value outside this range to be "special". For example, Cocoa has the value NSNotFound, which NSArray will return if you ask for the index of an object that is not in the array. It is defined as the largest possible NSInteger. You could reuse this yourself if your Y value will never be NSIntegerMax.
The other option, assuming you don't want to create a special type just for this, would be to have your method return both Y and whether or not Y was actually found. For example, some rough pseudocode:
- (NSInteger)yForX:(NSInteger)x wasFound:(BOOL *)found {
if (yWasFound) {
if (found)
*found = YES;
return y;
} else {
if (found)
*found = NO;
return 0;
}
}
You could use NSNumber, as some have suggested, but I find it a little awkward to deal in NSNumbers just to get nil.

NSMutableArray: How add a sorting value (int) to array's objects AFTER sorting it?

Got a tableView with some player objects in it, sorted ASC by best playerTime after each game try a player makes.
Now I want to add a value (int) that shows the players placement in the playerlist (tableview), that will be reflected on the the players custom cell in the tableView. Got the custom cell working already with the dynamic data, just I need the "placement" int.
How do I handle the array to do this? Must be done after the list (NSArray) been sorted by best playerTime.
I guess, some kind of iteration step one and two maybe (like an if-then statement)?
Maybe there is a smart NSArray property for this specific need?
Any tips or suggestions? Thank's.
Just display the row's value into your custom cell's label:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//...
myCustomCell.positionLabel.text = [NSString stringWithFormat:#"%i", (indexPath.row + 1)];
//...
}
Now if you have a player object and want to retrieve its position in your sorted array, you just do this:
int playerPosition = [mySortedArray indexOfObject:playerObject] + 1;

Resources