我的数组为我正在寻找的对象的索引返回了错误的数字。我的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
}
这是我的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
答案 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>
在您的示例代码中:
[defaults objectForKey:@"chamber filter
category"]
,我不确定defaults
是由什么构成的。NSString
的元素。但是
数组的对象是placesChamber
类型和哈希码
两种不同的类型从不匹配,你总是得到NSNotFound
结果。NSNumber
而不是NSString
。所以上面的逻辑也在这里。所以很明显你会得到NSNotFound
(2147483647)作为偶然的结果。
我相信你试图从数组中返回一个对象的索引(实际上是一个placesChamber
的类型),它具有与你的测试标准相匹配的属性。为此,您可以使用indexOfObjectPassingTest:
方法来编写比较逻辑。在块中,您可以编写自己的自定义逻辑,将数组项与搜索条件匹配,并相应地返回对象索引。
如果您想了解更多详情,请与我们联系。 快乐的编码。