Array annotation strangeness

  • Back on iterating through a mapKit annotation array, I'm bending my brain cell on this one.

    All my annotations are instances of the MyLocation class

    I added a method to expose the properties I want to save by returning a dict to the class.

    After all annotations are added, and I want to walk the array and build an array of annotations, I do this:

    - (IBAction)saveData:(id)sender
    {
      for (NSDictionary * myAnnotation in self.mapView.annotations)
      {
      MyLocation *tempLocation = [[MyLocation alloc] init ];

      // test that the methods in the MyLocation objects actually work on an empty object
      NSString *myString = [tempLocation name];
      NSDictionary *myDict = [tempLocation returnCoordinatesInDict];
      NSDictionary *myStuffDict = [tempLocation returnPropertiesInDict];
      // Try it with one of the MyLocation objects in the annotation array
      NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];

    Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'

    But if I comment out that line, set a breakpoint, it clearly shows that myAnnotation is a myLocation instance just like tempLocation.

    Does anyone know what I am missing here?

    Thanks,
    - Alex
  • Hi Alex-

    When enumerating the array, you've defined the objects in the collection as NSDictionary (which doesn't have that method)...

    for (NSDictionary * myAnnotation in self.mapView.annotations)

    Change the above to:

    for (MyLocation * myAnnotation in self.mapView.annotations)

    And the compiler should be happier...

    Hope this helps!

    John

    On May 9, 2012, at 12:09 PM, Alex Zavatone wrote:

    > Back on iterating through a mapKit annotation array, I'm bending my brain cell on this one.
    >
    > All my annotations are instances of the MyLocation class
    >
    > I added a method to expose the properties I want to save by returning a dict to the class.
    >
    > After all annotations are added, and I want to walk the array and build an array of annotations, I do this:
    >
    > - (IBAction)saveData:(id)sender
    > {
    > for (NSDictionary * myAnnotation in self.mapView.annotations)
    > {
    > MyLocation *tempLocation = [[MyLocation alloc] init ];
    >
    > //    test that the methods in the MyLocation objects actually work on an empty object
    > NSString *myString = [tempLocation name];
    > NSDictionary *myDict = [tempLocation returnCoordinatesInDict];
    > NSDictionary *myStuffDict = [tempLocation returnPropertiesInDict];
    > //    Try it with one of the MyLocation objects in the annotation array
    > NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];
    >
    > Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'
    >
    > But if I comment out that line, set a breakpoint, it clearly shows that myAnnotation is a myLocation instance just like tempLocation.
    >
    > Does anyone know what I am missing here?
    >
    > Thanks,
    > - Alex
  • This is what I get for copying and pasting code.

    Thank you.

    On May 9, 2012, at 2:28 PM, John Pannell wrote:

    > Hi Alex-
    >
    > When enumerating the array, you've defined the objects in the collection as NSDictionary (which doesn't have that method)...
    >
    > for (NSDictionary * myAnnotation in self.mapView.annotations)
    >
    > Change the above to:
    >
    > for (MyLocation * myAnnotation in self.mapView.annotations)
    >
    > And the compiler should be happier...
    >
    > Hope this helps!
    >
    > John
    >
    >
    > On May 9, 2012, at 12:09 PM, Alex Zavatone wrote:
    >
    >> Back on iterating through a mapKit annotation array, I'm bending my brain cell on this one.
    >>
    >> All my annotations are instances of the MyLocation class
    >>
    >> I added a method to expose the properties I want to save by returning a dict to the class.
    >>
    >> After all annotations are added, and I want to walk the array and build an array of annotations, I do this:
    >>
    >> - (IBAction)saveData:(id)sender
    >> {
    >> for (NSDictionary * myAnnotation in self.mapView.annotations)
    >> {
    >> MyLocation *tempLocation = [[MyLocation alloc] init ];
    >>
    >> //    test that the methods in the MyLocation objects actually work on an empty object
    >> NSString *myString = [tempLocation name];
    >> NSDictionary *myDict = [tempLocation returnCoordinatesInDict];
    >> NSDictionary *myStuffDict = [tempLocation returnPropertiesInDict];
    >> //    Try it with one of the MyLocation objects in the annotation array
    >> NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];
    >>
    >> Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'
    >>
    >> But if I comment out that line, set a breakpoint, it clearly shows that myAnnotation is a myLocation instance just like tempLocation.
    >>
    >> Does anyone know what I am missing here?
    >>
    >> Thanks,
    >> - Alex
    >
  • On May 9, 2012, at 11:09 AM, Alex Zavatone wrote:

    > - (IBAction)saveData:(id)sender
    > {
    > for (NSDictionary * myAnnotation in self.mapView.annotations)

    Here you type 'myAnnotation' as an NSDictionary*.

    > NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];
    >
    > Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'

    As such, the compiler tells you that an NSDictionary (which is the type you've assured it 'myAnnotation' is) does not implement the method you are trying to call on it.

    --
    David Duncan
  • On May 9, 2012, at 1:09 PM, Alex Zavatone wrote:

    > Back on iterating through a mapKit annotation array, I'm bending my brain cell on this one.
    >
    > All my annotations are instances of the MyLocation class
    >
    > I added a method to expose the properties I want to save by returning a dict to the class.
    >
    > After all annotations are added, and I want to walk the array and build an array of annotations, I do this:
    >
    > - (IBAction)saveData:(id)sender
    > {
    > for (NSDictionary * myAnnotation in self.mapView.annotations)
    > {
    > MyLocation *tempLocation = [[MyLocation alloc] init ];
    >
    > //    test that the methods in the MyLocation objects actually work on an empty object
    > NSString *myString = [tempLocation name];
    > NSDictionary *myDict = [tempLocation returnCoordinatesInDict];
    > NSDictionary *myStuffDict = [tempLocation returnPropertiesInDict];
    > //    Try it with one of the MyLocation objects in the annotation array
    > NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];
    >
    > Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'
    >
    > But if I comment out that line, set a breakpoint, it clearly shows that myAnnotation is a myLocation instance just like tempLocation.
    >
    > Does anyone know what I am missing here?

    You lied to the compiler.

    You told it that myAnnotation was an NSDictionary:
    > for (NSDictionary * myAnnotation in self.mapView.annotations)

    even though you knew it was suppose to be a MyLocation (and so it rightly protested when you tried do [myAnnotation returnPropertiesInDict] since NSDictionary doesn't implement returnPropertiesInDict.

    Try:
    for (MyLocation * myAnnotation in self.mapView.annotations)

    Glenn Andreas                      <gandreas...>
    The most merciful thing in the world ... is the inability of the human mind to correlate all its contents - HPL
  • On 9 May 2012, at 1:09 PM, Alex Zavatone wrote:

    > Back on iterating through a mapKit annotation array, I'm bending my brain cell on this one.
    >
    > All my annotations are instances of the MyLocation class
    >
    > I added a method to expose the properties I want to save by returning a dict to the class.
    >
    > After all annotations are added, and I want to walk the array and build an array of annotations, I do this:
    >
    > - (IBAction)saveData:(id)sender
    > {
    > for (NSDictionary * myAnnotation in self.mapView.annotations)

    Assuming .mapView is an MKMapView, then .annotations is an NSArray of objects that conform to <MKAnnotation>. From what you say, the objects in the array are of class MyLocation, which I gather is not a subclass of NSDictionary. (Leave aside that subclassing NSDictionary is ill-advised.)

    Therefore your declaration of the myAnnotation loop variable is mistaken: Whether you declare the object pointer to be an NSDictionary or not, in point of fact the object itself is a MyAnnotation. Objective-C has no C++-like concept of producing new, converted objects upon casting.

    > {
    > MyLocation *tempLocation = [[MyLocation alloc] init ];
    >
    > //    test that the methods in the MyLocation objects actually work on an empty object
    > NSString *myString = [tempLocation name];
    > NSDictionary *myDict = [tempLocation returnCoordinatesInDict];
    > NSDictionary *myStuffDict = [tempLocation returnPropertiesInDict];
    > //    Try it with one of the MyLocation objects in the annotation array
    > NSDictionary *myGoodsDict = [myAnnotation returnPropertiesInDict];
    >
    > Xcode will not let the last line compile with a "Receiver type 'NSDictionary' for instance message does not declare a method with selector 'returnPropertiesInDict'
    >
    > But if I comment out that line, set a breakpoint, it clearly shows that myAnnotation is a myLocation instance just like tempLocation.

    Yes: a MyLocation. Not an NSDictionary. But you told the compiler that myAnnotation is an NSDictionary (even though it isn't), and it doesn't know anything different. NSDictionary does not declare a -returnPropertiesInDict method, and that's what the compiler is complaining about.

    — F

    --
    Fritz Anderson -- Xcode 4 Unleashed: Due 21 May 2012 -- <http://x4u.manoverboard.org/>
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today