我有一个类,我正在使用文本标签传递选择器:
@interface TableLink : NSObject
@property (nonatomic, strong) NSString* name;
@property (nonatomic) NSInteger identifier;
@property (nonatomic) SEL selector;
@end
@implementation TableLink
- (id) initWithName: (NSString*) name identifier: (NSInteger) identifier selector: (SEL) selector
{
if (self = [super init])
{
self.name = name;
self.identifier = identifier;
self.selector = selector;
}
return self;
}
- (BOOL) isEqual: (id) anObject
{
if (self == anObject)
{
return YES;
}
else if ([anObject isKindOfClass: [self class]])
{
return [self.name isEqualToString: [anObject name]];
}
else if ([anObject isKindOfClass: [NSString class]])
{
return [self.name isEqualToString: anObject];
}
else
{
return NO;
}
}
- (NSUInteger) hash
{
return [self.name hash];
}
@end
我设置了这些对象的可变数组,如下所示:
+ (NSMutableArray*) buttonNames
{
NSArray* names = [self determineActiveNames];
NSMutableArray* buttons = [NSMutableArray arrayWithCapacity: names.count];
for (int i = 0; i < names.count; i++)
{
NSString* s = [NSString stringWithFormat: @"show%@", names[i]];
s = [s stringByReplacingOccurrencesOfString: @" " withString: @""];
SEL sel = NSSelectorFromString(s);
TableLink* tl = [[TableLink alloc] initWithName: names[i] identifier: i selector: sel];
[buttons addObject: tl];
}
return buttons;
}
以下是我如何称之为删除:
- (void) hideEntry: (NSString*) entry
{
[self.buttons removeObject: entry];
[self.tableView reloadData];
}
但是当我尝试使用[self.buttons removeObject: someNSString];
删除它时,它不会从我的数组中删除任何内容。我在我的isEqual:
电话中放了一个断点,但它没有被调用。我是否遗漏了某些内容以使其使用我的平等测试,或者[NSMutableArray removeObject:]
没有使用isEqual:
(文档中说它确实如此)?
当我用以下内容替换对removeObject:
的调用时,它会按预期删除我的条目。它显然不会调用我的isEqual:
或hash
,但它会得到我想要的结果。我仍然想知道为什么它不起作用,以防我将来需要覆盖isEqual。
for (NSUInteger i = 0; i < self.buttons.count; i++)
{
if ([[self.buttons[i] name] isEqualToString: entry])
{
[self.buttons removeObjectAtIndex: i];
break;
}
}
答案 0 :(得分:1)
每当您实施hash
时,您还必须实施isEqual:
方法。
两个被认为相等的对象也必须返回相同的hash
值。
你可以做一些简单的事情:
- (NSUInteger)hash {
return [self.name hash];
}
顺便说一句 - 你的isEqual:
方法都错了。它必须是:
- (BOOL)isEqual:(id)anObject {
if (anObject == self) {
return YES;
} else if ([anObject isKindOfClass:[self class]]) {
// This should probably also compare the identifier and maybe the selector too
return [self.name isEqualToString:[anObject name]];
} else if ([anObject isKindOfClass:[NSString class]]) {
// Allow for comparison with a string
return [self.name isEqualToString:(NSString *)anObject];
} else {
return NO;
}
}
正如您所做的那样,您尝试将self.name
与正在比较的任何对象进行比较。由于您有一组TableLink
个对象,因此将self.name
与TableLink
个对象进行比较。他们永远不会平等。
答案 1 :(得分:1)
您认为可变数组中有一个TableLink对象,您将其名称作为NSString *传递,并且您认为removeObject将调用[someTableLink isEqual:someString]来查找要删除的TableLink对象。但它调用[someString isEqual:someTableLink]的可能性很小,而是调用NSString isEqual。
你所做的只是危险,会让你陷入困境。如果您确定按钮名称是唯一的,请将链接放入名称为键的NSDictionary中。