无法从NSMutableArray获取对象

时间:2013-02-24 21:54:21

标签: objective-c indexing nsmutablearray

在我的应用中,有一个mapView,用户可以通过按屏幕添加注释。当注释被放到mapView上时,它们会被添加到单例中的可变数组中。注释视图有一个callout按钮,当按下它时,它会将详细视图(称为PinViewController)推入堆栈。我的问题是,当按下callout按钮时,我想将该注释对象的索引传递给详细视图控制器,以便我可以从该对象获取地址和日期。但每当我按下callout按钮时,无论它是哪个注释,它总是传递数组中第一个对象的索引。我不明白我做错了什么,有人可以帮帮我吗?这是一些代码:

- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control {

    PinViewController *pvc = [[PinViewController alloc]init];
    [[self navigationController]pushViewController:pvc animated:YES];
    NSUInteger pinIndex = [[Data singleton].annotations indexOfObject:view.annotation];
    [pvc setIdentifier:pinIndex];
} 

这是来自详细视图控制器:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.labelView setFrame:CGRectMake(10, 260, 300, 230)];
    [PinViewController roundView:self.labelView onCorner:UIRectCornerAllCorners radius:15];
    [[self view]addSubview:self.labelView];

    self.annotation = [[Data singleton].annotations objectAtIndex:self.identifier];
    self.addressLabel.text = self.annotation.address;
    self.dateLabel.text = self.annotation.subtitle;
}

以下是将注释添加到数组的位置:

- (void)press:(UILongPressGestureRecognizer *)recognizer {
    CGPoint touchPoint = [recognizer locationInView:self.worldView];
    CLLocationCoordinate2D touchMapCoordinate = [self.worldView convertPoint:touchPoint toCoordinateFromView:self.worldView];

    self.geocoder = [[CLGeocoder alloc]init];
    CLLocation *location = [[CLLocation alloc]initWithCoordinate:touchMapCoordinate
                                                        altitude:CLLocationDistanceMax
                                              horizontalAccuracy:kCLLocationAccuracyBest
                                                verticalAccuracy:kCLLocationAccuracyBest
                                                       timestamp:[NSDate date]];
    [self.geocoder reverseGeocodeLocation:location
                   completionHandler:^(NSArray *placemarks, NSError *error) {
                       //NSLog(@"reverseGeocoder:completionHandler: called");
                       if (error) {
                           NSLog(@"Geocoder failed with error: %@", error);
                       } else {
                           CLPlacemark *place = [placemarks objectAtIndex:0];
                           self.geocodedAddress = [NSString stringWithFormat:@"%@ %@, %@ %@", [place subThoroughfare], [place thoroughfare], [place locality], [place administrativeArea]];
                           if (UIGestureRecognizerStateBegan == [recognizer state]) {
                               self.addressPin = [[MapPoint alloc]initWithAddress:self.geocodedAddress
                                                                   coordinate:touchMapCoordinate
                                                                        title:self.geocodedAddress];
                               [[Data singleton].annotations addObject:self.addressPin];
                               [self.worldView addAnnotation:self.addressPin];
                               NSLog(@"The number of pins in the annotation array is: %u",[Data singleton].annotations.count);
                           }
                       }
                   }];
}

基本上,传递给PinViewController的索引总是0,无论它是哪个注释。我不明白为什么这段代码不起作用。

1 个答案:

答案 0 :(得分:3)

NSArray indexOfObject方法在每个数组成员上调用isEqual以确定它们是否相同。你确定你的对象只有在它们真正相等的情况下才会返回YES吗?我怀疑你的对象返回YES,即使它们是不等的

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html

  

从索引0开始,数组的每个元素都发送一个isEqual:   消息,直到找到匹配或到达数组的末尾。   此方法将anObject参数传递给每个isEqual:消息。   如果isEqual:对象被认为是相等的(在NSObject中声明   protocol)返回YES。

像NSNumber这样的基础类已经为你实现了isEqual,因此你可以在数组indexOfObjects方法中立即使用它

NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:[NSNumber numberWithInt:3]];
[arr addObject:[NSNumber numberWithInt:2]];

[arr indexOfObject:[NSNumber numberWithInt:2]]; // gives 1

但是,当您实现自定义类(例如MapView)时,Objective C不知道如何比较您的对象,因此您必须自己实现isEqual比较器

假设MapView有一个名为cow的整数属性,您可以从中确定相等性(例如:如果两个MapView具有相同的cow值,那么它们是相等的) ,你会写这样的东西:

@interface MapView : NSObject {

}

@property (nonatomic, assign) int cow;

- (BOOL)isEqual:(id)object


@implementation MapView

@synthesize cow

- (BOOL) isEqual:(id)object
{
    MapView* otherMapview = (MapView*) object;

    return cow == otherMapview.cow;
}