Find number of objects in NSMutableArray - objective-c

I have a problem with counting numbers of object in nsmutablearray. I have this code:
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSUInteger numObjects = [selected count];// selected is nsmutablearray
for ( int i = 0; i<numObjects; i++)
{
NSLog(#"%# == %# , nr.object =%#",[AnotherArray objectAtIndex:indexPath.row], [selektuara objectAtIndex:i], numObjects); // here stops the by reporting this: Program recived signal: "EXC_BAD_ACCESS"
if ([selected objectAtIndex:i] == [AnotherArray objectAtIndex:indexPath.row])
{
NSLog(#"%#",[selected objectAtIndex:i]);
return UITableViewCellAccessoryCheckmark;
}
else
{
return UITableViewCellAccessoryNone;
}
}
}
When i remove NSLog for numbers of object, it counts only one object and compare only that.
So has anyone else another solution how to get this number?
Thanks.

Error in using NSLog:
NSLog(#"%# == %# , nr.object =%d",[AnotherArray objectAtIndex:indexPath.row], [selektuara objectAtIndex:i], numObjects);
As numObjects is NSUInteger you should use %d to print its value.
Error in comparing:
if ([[selected objectAtIndex:i] compare:[AnotherArray objectAtIndex:indexPath.row]] == NSOrderedSame)
You shouldn't use == for comparing objects in Objective-C

You must not try to output an unsigned integer with the %# format specifier. Use %u instead.

Related

Error querying filter in Hebrew

I have the following code:
NSMutableArray *getDatosSelect=nil;
NSMutableString *consulta=[[NSMutableString alloc]init];
[consulta appendString:#"SELECT idOzDiccionario, espanyol, ingles, hebreo, fonetica FROM ozdiccionario WHERE UPPER(ingles) LIKE 'FRIEND%'"];
if ( sqlite3_prepare_v2(sql,[consulta UTF8String],[consulta length],&resultado,&siguiente) == SQLITE_OK ){
getDatosSelect=[[NSMutableArray alloc] init];
while (sqlite3_step(resultado)==SQLITE_ROW){
NSMutableArray *datos=[[NSMutableArray alloc] init];
for (int x=0; x<sqlite3_column_count(resultado); x++) {
char *pChar=(char *)sqlite3_column_text(resultado, x);
if (pChar!=nil) {
[datos addObject:[NSString stringWithUTF8String: pChar]];
}
}
[getDatosSelect addObject:datos];
datos=nil;
}
}else {
NSString *errores=[NSString stringWithFormat:#"%s", sqlite3_errmsg(sql)];
NSLog(#"%# %#",TAG,errores);
}
which runs correctly while if I run this other code
NSMutableArray *getDatosSelect=nil;
NSMutableString *consulta=[[NSMutableString alloc]init];
[consulta appendString:#"SELECT idOzDiccionario, espanyol, ingles, hebreo, fonetica FROM ozdiccionario WHERE hebreo='חבר'"];
if ( sqlite3_prepare_v2(sql,[consulta UTF8String],[consulta length],&resultado,&siguiente) == SQLITE_OK ){
getDatosSelect=[[NSMutableArray alloc] init];
while (sqlite3_step(resultado)==SQLITE_ROW){
NSMutableArray *datos=[[NSMutableArray alloc] init];
for (int x=0; x<sqlite3_column_count(resultado); x++) {
char *pChar=(char *)sqlite3_column_text(resultado, x);
if (pChar!=nil) {
[datos addObject:[NSString stringWithUTF8String: pChar]];
}
}
[getDatosSelect addObject:datos];
datos=nil;
}
}else {
NSString *errores=[NSString stringWithFormat:#"%s", sqlite3_errmsg(sql)];
NSLog(#"%# %#",TAG,errores);
}
I get the following error:
unrecognized token: ""◊ó◊ë◊"
This error occurs when the method converts a string to UTF8 character
Why? What is the problem?
You've used [consulta length] as the number of bytes in consulta. That is not correct. length is the number of characters. The number of bytes could be more, and Hebrew generally will be. To get the length, you need to use:
[consulta lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
It is likely that your queries are being truncated, so they may or may not work depending on their exact content.

Part of NSString to NSNumber

I need to input x and y co-ordinates into a custom object, the input is with the format "x,y"
I am currently storing the input as an NSString and need to get the integers out of it and into separate NSNumbers. If there is another way to store the input that would be easier, please explain.
I need to store x and y as separate NSNumbers, this also this needs to account for if x and y are 2 digits. i.e. "23,4"
can anyone help?
Use -[NSString componentsSeparatedByString:]
NSArray *numericComponents = [string componentsSeparatedByString:#","];
NSArray *numbers = [numericComponents map:^id(NSString *object) {
return #([object integerValue]);
}];
map here is simply a category method that I've added to NSArray:
#implementation NSArray (JRAdditions)
- (NSArray *)map:(id(^)(id))block {
if([self count] == 0 || block == nil) return self;
NSMutableArray *mapped = [NSMutableArray new];
NSArray *copy = [self copy];
for(id obj in copy) {
id mappedObject = block(obj);
if(mappedObject) {
[mapped addObject:mappedObject];
}
}
return [mapped copy];
}
#end
NSString *str=#"23,4";
NSArray *array=[str componentsSeparatedByString:#","];
NSNumber *xNum=#([array[0] integerValue]);
NSNumber *yNum=#([array[1] integerValue]);
To check if they are two digits :
if ([xNum integerValue]>9 && [xNum integerValue]<100) {
NSLog(#"x is 2 digits");
}
else{
}
if([yNum integerValue]>9 && [yNum integerValue]<100) {
NSLog(#"y is 2 digits");
}
else{
}

Sending __string to __unsafe_unretained changes retain/release properties of pointer

Following is a code segment which I learnt in a lynda iOS training course based on iOS 4 (without ARC).
I was going to implement the same code in my Xcode 4.2 which has ARC turned on with the iOS 5 SDK. It gave me this error:
error: Semantic Issue: Sending '__strong id *' to parameter of type '__unsafe_unretained id **' changes retain/release properties of pointer"
- (NSNumber *) insertRow:(NSDictionary *) record {
// NSLog(#"%s", __FUNCTION__);
int dictSize = [record count];
// the values array is used as the argument list for bindSQL
id keys[dictSize]; // not used, just a side-effect of getObjects:andKeys
id values[dictSize];
[record getObjects:values andKeys:keys]; // convenient for the C array
// construct the query
NSMutableArray * placeHoldersArray = [NSMutableArray arrayWithCapacity:dictSize];
for (int i = 0; i < dictSize; i++) // array of ? markers for placeholders in query
[placeHoldersArray addObject: [NSString stringWithString:#"?"]];
NSString * query = [NSString stringWithFormat:#"insert into %# (%#) values (%#)",
tableName,
[[record allKeys] componentsJoinedByString:#","],
[placeHoldersArray componentsJoinedByString:#","]];
[self bindSQL:[query UTF8String] arguments:(va_list)values];
sqlite3_step(statement);
if(sqlite3_finalize(statement) == SQLITE_OK) {
return [self lastInsertId];
} else {
NSLog(#"doQuery: sqlite3_finalize failed (%s)", sqlite3_errmsg(database));
return [NSNumber numberWithInt:0];
}
}
** The real case came with the following segment of this whole function.**
int dictSize = [record count];
// the values array is used as the argument list for bindSQL
id keys[dictSize]; // not used, just a side-effect of getObjects:andKeys
id values[dictSize];
[record getObjects:values andKeys:keys]; // convenient for the C array
How can I resolve this?
There's a lot wrong with that function. The fix for your compiler error is simply to declare keys and values with the __unsafe_unretained ownership qualifier:
__unsafe_unretained id keys[dictSize]; // not used, just a side-effect of getObjects:andKeys
__unsafe_unretained id values[dictSize];
However, the cast (va_list)values is undefined behavior. Don't do it.
Since you're not using the keys array at all, it would be better to do something like this:
- (NSNumber *) insertRow:(NSDictionary *) record {
int count = [record count];
NSMutableArray * placeHoldersArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count; i++) {
[placeHoldersArray addObject: #"?"];
}
NSString * query = [NSString stringWithFormat:#"insert into %# (%#) values (%#)",
tableName,
[[record allKeys] componentsJoinedByString:#","],
[placeHoldersArray componentsJoinedByString:#","]];
[self bindSQL:[query UTF8String] arguments:[record allValues]];
sqlite3_step(statement);
if(sqlite3_finalize(statement) == SQLITE_OK) {
return [self lastInsertId];
} else {
NSLog(#"doQuery: sqlite3_finalize failed (%s)", sqlite3_errmsg(database));
return [NSNumber numberWithInt:0];
}
}
And then modify bindSQL:arguments: to take an NSArray * instead of a va_list. If you need help doing that, show us the source code of bindSQL:arguments:.
(However, I don't think it's documented that allKeys and allValues return parallel arrays…)
Edited for const char pointer:
- (NSNumber *) insertRow:(NSDictionary *) record {
NSArray * placeHoldersArray = [NSArray array];
const char * cStrings[record.count];
NSArray * keys = [record allKeys];
NSUInteger i=0;
for (id key in keys) {
id object = [record objectForKey:key];
if ([object isKindOfClass:[NSString class]])
cStrings[i++] = [(NSString*)object UTF8String];
else
#throw [NSException exceptionWithName:NSInvalidArgumentException reason:#"Expected NSString" userInfo:nil];
placeHoldersArray = [placeHoldersArray arrayByAddingObject: #"?"];
}
NSString * query = [NSString stringWithFormat:#"insert into %# (%#) values (%#)",
tableName,
[keys componentsJoinedByString:#","],
[placeHoldersArray componentsJoinedByString:#","]];
[self bindSQL:[query UTF8String] arguments:(va_list)cStrings];
sqlite3_step(statement);
if(sqlite3_finalize(statement) == SQLITE_OK) {
return [self lastInsertId];
} else {
NSLog(#"doQuery: sqlite3_finalize failed (%s)", sqlite3_errmsg(database));
return [NSNumber numberWithInt:0];
}
}
In the update method, you should understand that a va_list is just a group of any number of arguments. It is assumed that the method that is called knows how to determine the type. An example of this is with NSLog. It uses the format string to determine the type of an unknown number of variables, which are passed in as a va_list, i.e. comma separated values. Because you only have one value, just pass in the value. I am sketchy on whether sqlite wants a c string or if it will take an integer in this case.

loop through array of dictionaries to find a value

I have an array of dictionaries that I would like to go through to find a matching value that I can then Count == Nth item of the array
Each item of the array looks like this
HMOD = 0;
MID = 39;
MOD = SOMETHING; // looking for this value
ID = 50;
So I would like to create a loop that goes through the array until it finds the matching value, then I use the number in the count as an reference to Index path in the next view..
I have written this peice of code which dosnt work... but hopefully it gives you an idea of the loop I am trying to create.
int count = 0;
while (singleName != [[ModArray valueForKey:#"MOD"] objectAtIndex:count]) {
count ++;
NSLog(#"%i", count);
}
SingleName is a NSString that I am using to match the MOD value in ModArray...
Any help would be greatly appreciated.
Here is a simpler solution by using valueForKey on the array of dictionaries,
Assuming that your modArray is like this,
NSArray *modArray = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObject:#"0" forKey:#"HMOD"],
[NSDictionary dictionaryWithObject:#"39" forKey:#"MID"],
[NSDictionary dictionaryWithObject:#"something" forKey:#"MOD"],
[NSDictionary dictionaryWithObject:#"50" forKey:#"ID"], nil];
And singleName has a value as "something"
NSString *singleName = #"something";
Fetch the array from modArray which has an object with key as "MOD",
NSArray *array = [modArray valueForKey:#"MOD"];
Check if singleName is present in this array. If yes, then get the first index of that object which will be same as the index of dictionary with key "MOD" in modArray.
if ([array containsObject:singleName]) {
NSLog(#"%d", [array indexOfObject:singleName]);
} else {
NSLog(#"%# is not present in the array", singleName);
}
Update:
If you want to do it in your way, only mistake was you were using != whereas you should have used isEqualToString. You should have done like this,
int count = 0;
while (![singleName isEqualToString:[[modArray valueForKey:#"MOD"] objectAtIndex:count]]) {
count ++;
NSLog(#"%i", count);
}
Your code looks all inside out. You state you have an array of dictionaries. Assuming ModArray is the array (based on the name) you might do this:
NSUInteger count = 0;
for (NSDictionary *dict in ModArray) { // iterate through the array
NSString *mod = dict[#"MOD"]; // get the value for MOD
if ([mod isEqualToString:singleName]) { // compare the two strings
break; // they match so exit the loop
}
count++
}
// count has the index of the dictionary with the matching MOD value
Edit: Based on ACB correcting my misunderstanding of NSArray valueForKey:, the only real issue is your use of using != to compare the two strings.
- This is Helpful when you search from Dictionary.
NSMutableArray *contentList;
NSMutableArray *filteredContentList;
BOOL isSearching;
// firstSection is array which already filled.
// contentList array for value of particular key
// filteredContentList is search array from actual array.
- (void)searchTableList {
NSString *searchString = searchBar.text;
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"frame_code beginswith[c] %#", searchString];
NSArray *filteredArr = [firstSection filteredArrayUsingPredicate:filterPredicate];
if(contentList.count > 0)
[contentList removeAllObjects];
[filteredContentList addObjectsFromArray:filteredArr];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar1 {
if ([searchBar1.text length] != 0)
isSearching = YES;
else
isSearching = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change - %d",isSearching);
//Remove all objects first.
[filteredContentList removeAllObjects];
if([searchText length] != 0) {
isSearching = YES;
[self searchTableList];
}
else {
isSearching = NO;
}
[tblFrameList_SComplete reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
[self searchTableList];
}

NSNumbers stored in NSMutableArray

I'm trying to store numbers in a NSMutableArray, but when I check it, all I get is garbage.
-(void)storeIntoArray:(int)indexInt
{
NSNumber *indexNum = [[NSNumber alloc] initWithInt:indexInt];
[last100 insertObject:indexNum atIndex:prevCount];
prevCount++;
if(prevCount > 100)
{
prevCount = 0;
cycledOnce = YES;
}
}
-(BOOL)checkArray:(int)indexInt
{
for(int i = 0;i < [last100 count];i++)
{
NSLog(#"Stored: %d",[last100 objectAtIndex:i]);
if (indexInt == (int)[last100 objectAtIndex:i]) {
NSLog(#"Same entry, trying again");
return YES;
}
}
return NO;
}
When I check, I'll get values back like Stored: 110577680 and just various garbage values.
You're printing the NSNumber object address, not its value. Try using intValue. Or, if you want to print the object directly, use %# rather than %d.
NSLog(#"Stored: %d",[last100 objectAtIndex:i]);
Should be:
NSLog(#"Stored: %#",[last100 objectAtIndex:i]);
NSNumber is an object not an integer.