iOS如何修复一个数组返回一个无法找到的对象的索引

时间:2014-02-20 22:26:23

标签: ios arrays ios7 nsarray

我的数组为我正在寻找的对象的索引返回了错误的数字。我的array.count告诉我数组中有248个对象,但返回的索引是2147483647.我看到这个post类似于我的问题。我使用了这篇文章中提出的相等测试,但没有弄清楚为什么会发生这种情况以及如何解决它。

这是我的代码:(用解决方案编辑)

-(void)getChamberPrimaryCategories
{
    NSString *docsDir;
    NSArray *dirPaths;

    chamberCategoryArray = [[NSMutableArray alloc] init];

    // Get the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains(
                                                   NSDocumentDirectory, NSUserDomainMask, YES);

    docsDir = dirPaths[0];

    // Build the path to the database file
    _databasePath = [[NSString alloc]
                     initWithString: [docsDir stringByAppendingPathComponent:
                                      @"the_app.db"]];

    NSLog(@"%@",_databasePath);

    NSFileManager *filemgr = [NSFileManager defaultManager];

    if ([filemgr fileExistsAtPath: _databasePath ] == NO)
    {
        const char *dbpath = [_databasePath UTF8String];

        if (sqlite3_open(dbpath, &_the_app_database) == SQLITE_OK)
        {
            //do nothing
        } else {
            NSLog(@"Failed to open database");
        }
    }

    const char *dbpath = [_databasePath UTF8String];
    sqlite3_stmt    *statement;

    if (sqlite3_open(dbpath, &_the_app_database) == SQLITE_OK)
    {

        NSString *querySQL;

        querySQL = @"SELECT DISTINCT CHAMBER_PRIMARY_CATEGORY FROM PLACES WHERE CHAMBER_PRIMARY_CATEGORY IS NOT '' AND CHAMBER_PRIMARY_CATEGORY IS NOT NULL ORDER BY CHAMBER_PRIMARY_CATEGORY ASC";


        const char *query_stmt = [querySQL UTF8String];

        if (sqlite3_prepare_v2(_the_app_database,
                               query_stmt, -1, &statement, NULL) == SQLITE_OK)
        {
            NSLog(@"Query the database now.");
            //            if (sqlite3_step(statement) != SQLITE_ROW) {
            //                NSLog(@"Not okay");
            //            }
            while (sqlite3_step(statement) == SQLITE_ROW) {

                NSLog(@"Getting Information:");

                placesChamber *chamberCategoryObject = [[placesChamber alloc]init];

                NSString *placesPrimaryChamberCategory = [[NSString alloc]
                                                          initWithUTF8String:
                                                          (const char *) sqlite3_column_text(
                                                                                             statement, 0)];
                chamberCategoryObject.primary_category = placesPrimaryChamberCategory;

                NSLog(@"%@",placesPrimaryChamberCategory);

                [chamberCategoryArray addObject:chamberCategoryObject];
            }//end while

        }//end if
        else
        {
            NSLog(@"There is nothing in this database!");
            NSLog(@"%s",sqlite3_errmsg(_the_kearney_app_database));
        }
        sqlite3_finalize(statement);
        sqlite3_close(_the_kearney_app_database);

        [chamberCategoryTableView reloadData];

        NSLog(@"content offset: %f",chamberCategoryTableView.contentOffset.y);
        if (chamberCategoryTableView.contentOffset.y == 0)
        {

            placesChamber *searchChamber = [[placesChamber alloc] init];
            searchChamber.primary_category = @"Women's Clothing";
            NSUInteger index = [chamberCategoryArray indexOfObject:searchChamber];
            if (index == NSNotFound) {
                // no such chamber category
                NSLog(@"no such thing found");
            } else {
                // Found it at index
                NSLog(@"found it!");
            }


        }//end if

    }//end if

}

Debugger Showing Object in Array

这是我的placeChamber.m :(需要解决方案)

#import "placesChamber.h"

@implementation placesChamber

@synthesize ID;
@synthesize name;
@synthesize type;
@synthesize category;
@synthesize latitude;
@synthesize longitude;
@synthesize primary_category;
@synthesize secondary_category;

- (BOOL)isEqual:(id)object
{
    if ( self == object ) {
        return YES;
    }

    if ( ![object isKindOfClass:[placesChamber class]] ) {
        return NO;
    }

    if ( ![primary_category isEqualToString:[object primary_category]] ) {
        return  NO;
    }

    return YES;
}

@end

2 个答案:

答案 0 :(得分:1)

正如我在评论中所述,您已使用chamberCategoryArray个对象的实例填充了placesChamber

但是,然后您尝试查找其中一个对象的索引,而不是通过传入placesChamber对象,而是传入NSString文字。这根本行不通。

你需要做这样的事情:

placesChamber *searchChamber = [[placesChamber alloc] init];
searchChamber.primary_category = @"Women's Clothing";
NSUInteger index = [chamberCategoryArray indexOfObject:searchChamber];
if (index == NSNotFound) {
    // no such chamber category
} else {
    // Found it at index
}

此代码假定您已在isEqual:类上实施了placesChamber方法,该方法会比较primary_category属性。

附注:标准惯例是类名以大写字母开头,而方法名和变量以小写开头。所有人都应该使用骆驼案。

鉴于此,您的课程应为PlacesChamber,且该属性应为primaryCategory

答案 1 :(得分:0)

编辑:

这是你在第一时间实际寻找的东西:

NSString* criteria = @"Women's Clothing";
int index = [chamberCategoryArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        placesChamber* item = obj;
        *stop = [item.primary_category isEqualToString:criteria];
        return *stop;
 }];

这里我演示了如何根据primary_category对象的placesChamber属性获取索引。同样的方法也适用于其他属性。

===============================================

我发现您在以下3行代码中使用了indexOfObject:

//1.
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForItem:[chamberCategoryArray indexOfObject:[defaults objectForKey:@"chamber filter category"]] inSection:0];

//2.
NSLog(@"index number: %lu",(unsigned long)[chamberCategoryArray indexOfObject:@"Women's Clothing"]);

//3.
if(NSNotFound == [chamberCategoryArray indexOfObject:[NSNumber numberWithInteger:1]]) {
    NSLog(@"not found");
}

并且您正在填充以下行中的chamberCategoryArray,该行使用placesChamber类型的对象填充数组:

[chamberCategoryArray addObject:chamberCategoryObject];

现在,如果您将indexOfObject:消息传递给NSArray(或其子类),它会遍历数组,向数组的每个对象发送isEqual:消息以获得相等性,如果有的话发现,它返回索引,否则返回NSNotFound(正如您所知)。并且这种相等比较基于每个包含对象的计算哈希码,也就是说,如果数组中的一个对象具有与要比较的对象相同的哈希码(在内部计算),则将它们视为相等。 / p>

在您的示例代码中:

  • 在1.您正在检查数组对象的哈希码 哈希码为[defaults objectForKey:@"chamber filter category"],我不确定defaults是由什么构成的。
  • 在2.您正在检查NSString的元素。但是 数组的对象是placesChamber类型和哈希码 两种不同的类型从不匹配,你总是得到NSNotFound 结果。
  • 在3.你做同样的错误,这次是NSNumber 而不是NSString。所以上面的逻辑也在这里。

所以很明显你会得到NSNotFound(2147483647)作为偶然的结果。

我相信你试图从数组中返回一个对象的索引(实际上是一个placesChamber的类型),它具有与你的测试标准相匹配的属性。为此,您可以使用indexOfObjectPassingTest:方法来编写比较逻辑。在块中,您可以编写自己的自定义逻辑,将数组项与搜索条件匹配,并相应地返回对象索引。

如果您想了解更多详情,请与我们联系。 快乐的编码。