我制作了这个简单的代码:
PO(self.last10000Places);
PO(PlaceMark);
NSMutableArray *placemarks= [NSMutableArray arrayWithArray:PlaceMark];
PO(placemarks);//Breakpoint1
[placemarks removeObjectsInArray:self.last10000Places];
PO(placemarks);//Breakpoint2
[self.last10000Places addObjectsFromArray:placemarks];
这里PO只是我的宏
#define CLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define PO(x) CLog(@#x ": %@", x)
#define PD(x) CLog(@#x ": %f", x)
现在,我知道nsmutablearray需要实现isEqual。
所以我把这段代码:
@interface CLLocation (equal)
- (BOOL)isEqual:(CLLocation*)other;
@end
@implementation CLLocation (equal)
- (BOOL)isEqual:(CLLocation*)other {
if ([self distanceFromLocation:other] ==0)
{
return true;
}
return false;
}
@end
@interface CLPlacemark (equal)
- (BOOL)isEqual:(CLPlacemark*)other;
@end
@implementation CLPlacemark (equal)
- (BOOL)isEqual:(CLPlacemark*)other {
PO(self);
PO(other);
if (![self.name isEqual:other.name])
{
return false;
}
if (![self.location isEqual:other.location ])
{
return false; //NEVER called
}
return true;//breakpoint3 but strange result
}
@end
然后我逐步完成代码。现在这很奇怪。
在断点1我看到了:
2012-09-22 21:40:53.959 GetAllDistricts[18381:c07] <0x74a7480 SDViewController.m:(82)> placemarks: (
"Ross Sea, Ross Sea @ <-77.43947520,-168.68218520> +/- 100.00m, region (identifier <-75.73637772,-0.00216940> radius 2140218.36) <-75.73637772,-0.00216940> radius 2140218.36m"
at breakpoint3 I saw:
2012-09-22 21:41:22.964 GetAllDistricts[18381:c07] <0xd77fab0 SDViewController.m:(37)> self: Alexander Island, Antarctica @ <-71.05224390,-70.87965290> +/- 100.00m, region (identifier <-70.73927686,-71.91489801> radius 258243.49) <-70.73927686,-71.91489801> radius 258243.49m
2012-09-22 21:41:22.964 GetAllDistricts[18381:c07] <0xd77fab0 SDViewController.m:(38)> other: South Atlantic Ocean, South Atlantic Ocean, Antarctica @ <-42.60533670,-21.93128480> +/- 100.00m, region (identifier <-41.51023865,-31.60774370> radius 4958095.65) <-41.51023865,-31.60774370> radius 4958095.65m
2012-09-22 21:41:22.965 GetAllDistricts[18381:c07] <0xd787390 SDViewController.m:(37)> self: South Atlantic Ocean, South Atlantic Ocean, Antarctica @ <-42.60533670,-21.93128480> +/- 100.00m, region (identifier <-41.51023865,-31.60774370> radius 4958095.65) <-41.51023865,-31.60774370> radius 4958095.65m
2012-09-22 21:41:22.965 GetAllDistricts[18381:c07] <0xd787390 SDViewController.m:(38)> other: South Atlantic Ocean, South Atlantic Ocean, Antarctica @ <-42.60533670,-21.93128480> +/- 100.00m, region (identifier <-41.51023865,-31.60774370> radius 4958095.65) <-41.51023865,-31.60774370> radius 4958095.65m
很明显,地标包含罗斯海。那么removeObjectsinArray
与南大西洋的isEqual
号召是什么?
此外,Rosspoint也不会被breakpoint2从地标中移除。
我实现了isEqual我没有实现hash
这是问题吗?
答案 0 :(得分:2)
我已经弄明白问题是什么。实现 - (NSUInteger)哈希以某种方式修复问题。
文档说我们在覆盖isEqual
时必须覆盖哈希看起来removeObjects使用哈希进行优化,并确定哈希是不相等的,并得出结论,isEqual将返回false而不进行检查。
所以我只需添加以下代码:
@interface CLLocation (equal)
- (BOOL)isEqual:(CLLocation*)other;
@end
@implementation CLLocation (equal)
- (BOOL)isEqual:(CLLocation*)other {
if ([self distanceFromLocation:other] ==0)
{
return true;
}
return false;
}
- (NSUInteger) hash
{
NSUInteger theHash = (NSUInteger) (self.coordinate.latitude *360 + self.coordinate.longitude);
CLog(@"thehash %d",theHash);
return theHash;
}
@end
@interface CLPlacemark (equal)
- (BOOL)isEqual:(CLPlacemark*)other;
@end
@implementation CLPlacemark (equal)
- (BOOL)isEqual:(CLPlacemark*)other {
PO(self);
PO(other);
if (![self.name isEqual:other.name])
{
return false;
}
if (![self.location isEqual:other.location ])
{
return false;
}
return true;
}
-(NSUInteger) hash
{
return self.name.hash;
}
答案 1 :(得分:1)
您的问题可以使用一些整理,也许是对当前行为的简要说明,以及它与预期的偏差。
但是,我想知道(基于你的问题的标题)你是否对arrayWithArray:
方法实际创建并维护一个单独的集合的事实感到困惑。您的对象不会被复制,但在这种情况下:
NSArray *objects = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
NSMutableArray *mute = [NSMutableArray arrayWithArray:objects];
NSArray *removals = [NSArray arrayWithObjects:@"A", @"C", nil];
[mute removeObjectsInArray:removals];
您的最终结果将是:
objects = { @"A", @"B", @"C" }
mute = { @"B" }
此示例是否有助于澄清任何内容?