Weird "Property 'coordinate' requires method '-coordinate'" error - iphone

I've gotten to a point where I'm starting to think this is may actually be a bug in Xcode, but to be sure, I'm asking it here. I was working on my app that uses MapKit and CoreLocation, but at some point I started getting the warning "Property 'coordinate' requires method '-coordinate'". At first I thought I was doing something wrong, as I did use the property coordinate for an MKPointAnnotation, but after I commented that out, the warning remained.
In fact, after I've commented out pretty much everything, I still get the warning. It tells me the file name and line number (the line with #end), but if I search for coordinate in that file, there aren't any results. The .h doesn't declare the property either, so I'm really lost as to where this error is coming from... I can provide you with code, of course, but I've commented so much stuff out that it doesn't really make any sense to post it here. Just a few memory management methods without any actual content other than sending a message to super...

Xcode is correct in telling you that you're required to implement -coordinate. This is a non-optional method of the MKAnnotation protocol.
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKAnnotation_Protocol/Reference/Reference.html
coordinate The center point (specified
as a map coordinate) of the
annotation. (required) (read-only)
#property (nonatomic, readonly)
CLLocationCoordinate2D coordinate
I believe the reason you can't synthesize coordinate is not because you didn't declare the property, but because you haven't told the compiler what storage to use.
Adding
CLLocationCoordinate2D coordinate;
to the fields (variables) section of your class interface will give the compiler the storage it is looking for.
Or you can point the compiler to other storage using this syntax:
#synthesize coordinate=myCoordinateVariable;
But none of that really matters, because you don't have to use synthesize.
Just implement the method yourself! The required part is readOnly so you only need to implement the getter.
-(CLLocationCoordinate2D)coordinate {
return myCoordinate;
}
#property and #synthesize are primarily shortcuts. #synthesize just says to the compiler - "Implement these accessors if I haven't". But normally you declare a property like this, right?
#implementation MyClass : NSObject {
NSString *someString;
}
#property (nonatomic, retain) NSString *someString;
and then you synthesize it. #synthesize creates the appropriate implementations for the declarations implied by #property:
-(NSString *)someString;
-(void)setSomeString:(NSString *);
and uses the storage you provided when you declared the instance variable, NSString *someString.
Incidentally, in Xcode 4 #synthesize automatically creates storage for you if it doesn't already exist.

I've had the same problem for over a year on one of my apps. Nobody has ever been able to offer an explanation. I just got to the point of adding a mapview to my latest app and had only gotten as far as adding the MapKit Framework to the project, declaring support for the MKMapViewDelegate and MKAnnotation protocols then I did the #imports for MapKit/MapKit.h and MapKit/MKAnnotation.h. Build the app and Bang! there's the warning.
So, I commented out the MKAnnotation protocol declaration and like magic the warning went away. The only conclusion I can come to is that this is an Xcode issue.

Very strange this problem. I just added the following line as Ball suggested and my warning disappeared.
#synthesize coordinate=myCoordinateVariable;
Thanks Ball for the info.

Related

Proper usage of #private variables / properties

All my research shows that there's no real usage for the #private directive - so I must be missing something and need you experts to chime in :-)
Assume we have 2 classes: a Car class and a SportsCar class, where SportsCar is a subclass of Car.
Here's the Car class:
#interface Car : NSObject {
NSString *make;
NSString *model;
#private
int numberOfBackSeatPassengers; // I'm making this a private iVar cause I'm just gonna
// say that all Sportscars will be 2-seaters and therefore shouldn't
// be able to set/get the number of back-seat passengers
}
#property (nonatomic, strong) NSString *make, *model;
// Now here's my first issue: if I also make "numberOfBackSeatPassengers" an #property
// then it seems like all subclasses of this Car class *WILL* be able to access it as
// well - even though I declared it as #private - but I'll do this anyway to make my point:
#property int numberOfBackSeatPassengers;
#end
The Implementation looks like this:
#implementation Car
#synthesize make, model, numberOfBackSeatPassengers;
#end
Now here's the Sportscar class:
#import "Car.h"
#interface Sportscar : Car
#property int turboEngineSize;
#end
And its implementation:
#import "Sportscar.h"
#implementation Sportscar
#synthesize turboEngineSize;
#end
In "main" I have this:
Car *car1 = [[Car alloc] init];
[car1 setMake:#"Chevy"];
[car1 setModel:#"Impala"];
[car1 setNumberOfBackSeatPassengers:3];
Sportscar *sports1 = [[Sportscar alloc] init];
[sports1 setMake:#"Audi"];
[sports1 setModel:#"tt"];
[sports1 setNumberOfBackSeatPassengers:3];
Obviously I'm able to set the NumberOfBackSeatPassengers on the Sportscar - even though that iVar was declared as #private - but that's because I made it an #property in "Car.h" which means that the synthesized getter and setter for it are Instance Methods, thereby available to all subclasses of Car.
The other option would have been to NOT declare numberOfBackSeatPassengers as an #property in "Car.h", keep it there as only a simple iVar, and instead manually create a Setter and Getter for it in the #implementation of "Car.m" like this:
-(void) setNumberOfBackSeatPassengers:(int)numPassgeners {
numberOfBackSeatPassengers = numPassgeners;
}
-(int)numberOfBackSeatPassengers {
return numberOfBackSeatPassengers;
}
This would have made the getter and setter for numberOfBackSeatPassengers available only within "Car.m" - which I suppose would make them "private" - but they'd be too private: I could never call them from Main, or from anywhere outside of "Car.m" Moreover, and this is the real point: doing it this way means the #private directive back in "Car.h" doesn't really come into play at all in any of this. I mean I could now go back to "Car.h", take out the "#private" directive there -- and my manual setter and getter for numberOfBackSeatPassengers would still work exactly the same as they are now, being supposedly private - so what's to be gained with "#private"? How does it truly come into play?
Can anyone shed any real light on this?
(And yes, I know I can extend my Car class in the #interface section of the "Car.m" file - through a category, or make numberOfBackSeatPassengers a readonly property first, then change it to readwrite, etc. - but these all seem like workarounds or "hacks" to making "#private" work. I just don't get how #private truly works on its own.)
=====================================================
EDIT - in response to aroth's comments below:
1) aroth's absolutely correct in saying that a subclass could still theoretically call a method that was NOT declared in its parent class's Header -- by using performSelector. I say "theoretically", cause in my case its not quite working correctly: if - in "main" - I call
[sportscar1 performSelector:#selector(setNumberOfBackSeatPassengers:)];
then I get some junk number inserted for numberOfBackSeatPassengers cause I can't explicitly pass-in a number as an argument when calling the method this way.
(Question: is there a way around this?)
2) aroth's also absolutely right in saying that in Sportscar we can simply override the Car class's setter and getter for numberOfBackSeatPassengers, and have these overriding methods reset it to 0, or give an error, etc. But while this is a very practical solution and seems to solve this particular problem, I feel like it doesn't address the larger issue of #private not really seeming to do what it ought to do.
3) Redesigning the logic to have a class for FourDoorCar and another one for TwoDoorCar and then continue building off of that is an interesting option - but that almost feels like now Objective-C's syntax is "forcing" itself on my programming logic and how I'm structuring my very project - and this feels like quite an imposition. Maybe I'm wrong and making too much out of this - but either way this all came about just because the #private isn't doing what it seems to promise...? Doesn't feel right.
At the end of the day I keep coming back to the same question: what good does #private actually do us? What benefits does it have, what does it "buy" me? It seems that if I want to have an iVar be private, I can just declare it in the ".m" file and not ever bother declaring it in the Header file in the first place. I mean am I right about this or not? or is there still some instance where you'd want to declare an iVar in the Header as #private, but not declare a setter and getter for it there in the Header - so those won't be explicitly available to subclasses - and have it all make sense?
Can we think of an actual example for this? Is there some sort of Car property that I'd want to declare as #private in the Header (as opposed to in the ".m") that would somehow benefit me?
I thought numberOfBackSeatPassengers would be a good example, but I'm not seeing how it'd really work in action, in actual code...
=========================================================================
EDIT #2 - Continuing the dialogue with #aroth :-)
#aroth - I absolutely agree that its much better/more organized to declare all iVars in the Header and not split things up so that some are in the Header and some are in the Implementation. That creates a mess and I really dislike that approach. (I noted in my original question that I don't want to use the Implementation and/or Category approach to address my question.)
-Also, yes, properties absolutely don't always have to be backed up by iVars.
-Regarding designing the Class appropriately, I concur that that of course is the key to good programming. The Car/Sportscar example is something I made up on the spot to give my question some context and I didn't invest any time considering its design merits/flaws. I think if we were to take your approach however - which seems quite logical for sure - and go with a Car class, a FourDoorCar subclass, a TwoDoorCar subclass, etc. - we could solve a lot of problems - but its still very likely that sooner or later we'll run into a situation where we'd perhaps want an #private iVar for one of our classes, and not want to create another subclass to deal with it.
I mean lets just assume that this would happen, for the sake of this discussion.
And so, if possible, I'd really like to think of a specific iVar for our Car class that it would make sense to have as #private, show in code how to use it, and discuss its scope and limitations.
I keep trying to think of a real-world example of some property of a Car that we would want only the Car to have - and that none of its subclasses should inherit.
I really thought numBackSeatPassengers would do the trick - and for the purposes of our discussion it still can, but, I'll just make up another one and call it phantomIVar :-)
And so:
#interface Car : NSObject {
#private
//int numberOfBackSeatPassengers;
int phantomIVar;
}
#property (nonatomic, strong) NSString *make, *model;
#end
The Implementation would be:
#implementation Car
#synthesize make, model;
-(void) setPhantomIVar:(int)i {
phantomIVar = i;
}
-(int)phantomIVar {
return phantomIVar;
}
#end
Which pretty much puts us back where we started :-)
At least that's how I feel.
I mean the only thing that the #private declaration seems to buy us is readability. So that now, anyone looking at the Header will be able to see that phantomIVar is an iVar of Car, and understand that its private. That's it.
In terms of functionality however, it didn't seem to do much. Cause its not like putting #private in front of phantomIVar freed us up to still be able write a setter/getter for it in the Header and have those be only accessible to Car class objects and not subclasses of Car. No, #private doesn't get you that. To get privacy you'd have to go in the Implementation file and write your setter and getter there. And ultimately in Objective-C there's no such thing as private methods. In Obj. C. they're all public.
aroth, please let me know if I got this right - and if not, where exactly I went wrong.
Many thanks :-)
This would have made the getter and setter for
numberOfBackSeatPassengers available only within "Car.m"
Not true. Those methods would still exist on every instance of Car and every instance of every object that extends Car, whether or not you declare them in your header file. The compiler wouldn't treat them as publicly visible and would complain if you tried to call them directly, but you'd still be able to call your getter and setter on any subclass of Car simply by using performSelector:.
In any case, if you have a #property there's no point is using #private on the ivar that backs it (and there's also no point in having an explicit ivar backing it, one will be created automatically for you when you use #synthesize; but that's a separate topic). I'd suggest that if SportsCar is meant to extend Car and never allow any backseat passengers to be recorded that the 'standard' way to do that would be to simply override the getter/setter methods in SportsCar to either always set/return 0 or to raise some error if an attempt is made to set a nonzero value.
Another option, since this property does not apply to all Car instances is to take it out of the base class entirely. You could, for example, have Car, and then derived from that have TwoDoorCar and FourDoorCar, and then have SportsCar be derived from TwoDoorCar. In this case you could declare numberOfBackSeatPassengers as a public property of FourDoorCar, as every four-door car should be able to accommodate passengers in the back seat.
To get back to the original question being asked, using #private on an ivar affects only the visibility of that ivar. It does not affect methods which make use of the ivar. So a subclass of Car will not be able to see the numberOfBackSeatPassengers ivar itself. But since you've created a public getter/setter for it, the subclass will of course be able to see those, and use them to modify the value of the ivar.
Edit
To briefly answer the updated question(s):
Yes, you can use NSInvocation to dynamically invoke a method that requires primitive parameters. Or you can use the approach discussed here, which is even more straightforward: Objective-C and use of SEL/IMP. Or you can use a NSNumber instead of an int and then use performSelector:withObject:.
I'm not sure what you're saying #private should be doing in this case. What is it that you think using #private should do?
I think this has less to do with syntax and more to do with principles of object-oriented design. If some cars do not have a back seat, then it is not really good object-oriented design to give the Car superclass a numberOfBackseatPassengers property. Doing that gives the object a field that does not actually apply to every instance of the object type. And when you start doing that you run into exactly the sort of problems you describe in your example. The purpose of a superclass is to contain functionality that is common to all of its derived types. If it has functionality that is common only to some of its derived types, then that is usually a design problem. In any case, it has nothing to do with Objective-C syntax or semantics.
As for what #private gets you, how about simplified organization of your class, for one thing? Yes you can declare an ivar in your implementation file to accomplish a similar effect, but is that really as convenient as having all the ivars declared in the header? On a reasonably complex project, will other developers be able to follow your code as easily if only some ivars are declared in the header and the rest are in the implementation file?
Without #private/#protected every ivar declared in a header would be public, which is definitely not good in an object-oriented environment for all the reasons Jonathan pointed out. So these access modifiers probably exist, first and foremost, to solve this issue.
As for use-cases, properties with getters/setters are probably not the best example. The purpose of getters/setters is virtually always to provide a public interface for modifying/querying the property value, and as noted in Objective-C it's not necessary to explicitly declare an ivar, in any scope, to back a synthesized property.
A better example may be IBOutlet's. You want these declared in your header so that XCode/Interface Builder can find them, but you don't want them exposed outside of your class implementation or (typically) even to subclasses of your class. So you would declare them in your header, and you generally would not add any getter/setter methods for these ivars.
Edit 2
For a specific example of where #private makes sense, what about something like:
#interface Car : NSObject {
#private
DataRecorder* blackBoxRecorder;
}
#property (nonatomic, strong) NSString *make, *model;
#end
We know that proposed regulations may require all cars on the road to include a built-in black-box/data recorder. So every Car must have one, and no subclass of Car should be able to tamper with blackBoxRecorder.
In this case having a setter method defined would not make sense. You might provide a public getter, or instead you might provide a public wrapper API around the DataRecorder that subclasses could use to log data. Something like -(void) logEventWithName:(NSString*)name andValue:(NSNumber*)value;. So subclasses can use the DataRecorder through the API, but they can't mess with the backing ivar itself to disable or modify the behavior of the mandated black-box/data recorder.
But in any case, yes, I'm in general agreement with your analysis. Having #private mostly impacts readability/maintainability of code. It needs to exist for Objective-C to be successful as an object-oriented programming language (if all ivars were public by default and there was no way to modify that, the language would be a complete mess), but what it does from a purely functional standpoint is not much. It's more of a logical/organizational tool. It assists with data hiding and allows you to keep all of your ivars in your header file(s), and that's about it.
You can declare the property as readonly in the Car class itself, or re-declare it as readonly only in the SportsCar class.
Also, #private doesn't have anything to do with properties - it only modifies the scope of the ivar itself.

Using id <delegate> as a property or parameter to a function

So I'm not sure how this works. I briefly looked at a coworker's C# (I'm not a .NET developer), and I see a lot of stuff that gets passed into methods would be some class object that conforms to an interface. Is this something that is good to do in objective-c as well?
For example, I'm messing around with the MapKit API and I created my own class that conforms to the MKAnnotation protocol so I can have custom views and some extra properties for the typical pin that gets dropped on the map. I plan on using this class I created,
Address : NSObject
as opposed to the MKPlacemark class when I place pins on the map. In my other view controllers and model classes, do I do:
#property (nonatomic, strong) id <MKAnnotation> object; //1
or
#property (nonatomic, strong) Address *object; //2
I started with the example 1, but then when I actually needed some of the properties of the Address object, I found myself having to typecast the object anyway which seemed like what's the point, or I'm missing the point? So I guess my end question is, is 1 or 2 better, and in what scenarios? Thanks.
I would go with option 3 which would look like this:
Address : NSObject <MKAnnotation>
Then when you implement the class, implement the methods required to conform to the MKAnnotation protocol.
This way you can have the best of both worlds.
Protocols are very similar to interfaces in languages such as C# or Java. One of the main differences is the ability to require certain methods and have other methods be optional. Since Objective-C is such a dynamic language, you'll see a number of calls such as [foo responseToSelector:#selector(someSelector:)]. If -someSelector: was marked as optional, you would need to check to see if the receiver "responds" to that message. If it were marked as required, however, the compile would throw up a warning if you didn't implement that method. Take a look at the Objective-C Language Reference for more information
You cannot use strong keyword for id type, use this instead:
#property (nonatomic, assign, readwrite) id<MyDelegate> delegate;

Not found in protocol error using associative objects

I have a bunch of MKPolygon saved in an array, but I wanted to save more data than the MKPolygon class has storage for (more specifically: a notes field that describes what that polygon is). Subclassing is, for some reason, not possible, so I found the associative objects feature that is, for my purposes, good enough. This is what my .m looks like:
#implementation MKPolygon (ExtraProperties)
static char notesKey;
- (void)setNotes:(NSString *)notes {
objc_setAssociatedObject(self, &notesKey, notes, 1);
}
- (NSString *)notes {
return objc_getAssociatedObject(self, &notesKey);
}
My .h just declares a property for this category:
#interface MKPolygon (ExtraProperties)
#property (nonatomic, retain) NSString *notes;
#end
Setting the notes property works well, no errors and it appears to store the variable. Getting it, on the other hand, works, but gives me a warning that -notes wasn't found in that protocol. It's probably important to let you know that the overlay is also added as annotation, and that I get this '-notes not found in protocol' error in my mapView:viewForAnnotation: method, for which the second argument is an id that conforms to the MKAnnotation protocol.
Now, I understand that it says that the MKAnnotation protocol doesn't implement the -notes method, but I never claim it does. I've created a category with two extra methods (getter/setter), so if my understanding of categories is correct, -notes is now considered to be a method of MKPolygon, correct? Then why is the compiler giving me this warning?
Also noteworthy: calling the method does actually work: I get the correct results, but I don't like having warnings in my code.
Since it is an MKAnnotation error.. Try implimenting it in your id... something like this probably..
id<MKAnnotation,NSObject> delegate;
"MKAnnotation" might be the wrong thing to put, you'd have to look it up in the xcode library but that's my best guess... good luck if it works, good-er luck if it doesn't /: haha

Objective-C properties are not being recognized in header file?

I wonder if I'm doing something completely stupid here... I'm clearly missing something. I've gotten used to the pattern of defining properties of a custom class, however I seem to be hitting a point where extended classes do not recognize new properties. Case of point, here's my header file:
#import <UIKit/UIKit.h>
#import "MyTableViewController.h"
#interface MyRootController : MyTableViewController {
NSMutableArray *sectionList;
}
#property (nonatomic, retain) NSMutableArray *sectionList;
#end
Now, for some reason that "sectionList" property is not turning green within my interface file (ie: it's not being recognized as custom property it seems). As a result, I'm getting all kinds of errors down in my implementation. The first is right at the top of my implementation where I try to synthesize the property:
#import "MyRootController.h"
#implementation MyRootController
#synthesize sectionList;
That synthesize line throws the error "No declaration of property 'sectionList' found in the interface". So, this is really confusing. I'm clearly doing something wrong, although I can't put my finger on what.
One thought: I am extending another custom class of my own. Do I need to specify some kind of super-class declaration to keep the architecture from getting sealed one level up?
Drat, it was a pathing issue. I still haven't figured out quite how XCode decides what folder to place new files into... and when two joined files end up in different folders, things don't work. Thanks for the reply, fbrereto.

Objective-C changes between OS 2.2.1 and OS 3?

When I tried compiling my app for OS 3 I encountered an the following error:
error: type of accessor does not match the type of property
The error was for a property I tried to access that is defined as follows:
NSMutableArray *myArray
#property (readonly,nonatomic) NSArray* myArray;
the property is #synthesized in the implementation file.
This worked just fine in OS 2.2.1 but doesn't is OS 3.0
Writing the getter method myself solved the problem.
Is anyone aware of changes to objective-c between OS 2.2.1 and 3.0?
Is there any documentation for these changes?
The API changes document doesn't appear to contain anything about this issue.
EDIT
the error occurs when you try to access the property e.g.
NSArray *anArray = myClass.myArray;
As I mentioned above I found a workaround for this: writing the getter method myself, however what I'm really after is some kind of documentation from apple explaining this change and any other changes that are not API related.
Thanks for your help
This is a compiler bug.
Though you didn't specify it completely, I expect your code looks like this:
#interface Foo : NSObject {
NSMutableArray *objects;
}
#property (readonly, copy) NSArray *objects;
#end
#implementation Foo
#synthesize objects;
#end
The compiler is, unfortunately, confused between the declaration of the objects property and the declaration of the objects instance variable. Remember that properties and instance variables are different things in Objective-C; a property can be backed by an instance variable, but it's really part of the public interface of a class.
You can work around this by changing your code to clearly separate the definition of the instance variable from the definition of the property, for example by prefixing the name of the instance variable:
#interface Foo : NSObject {
NSMutableArray *_objects;
}
#property (readonly, copy) NSArray *objects;
#end
#implementation Foo
#synthesize objects = _objects;
#end
This way the compiler doesn't get confused about the property versus the instance variable in expressions like self.objects (which it shouldn't anyway, but apparently does).
Just to head off the inevitable response: Apple does not reserve the underbar prefix for instance variables. It's reserved for methods. Regardless, if you dislike the underbar, feel free to use another prefix.
edit: Original answer removed after peer review found it lacking. Please read Chris Hanson's comments on the matter. I'm leaving the rest here because I think it is still valid.
Note that even if you declare the property type to be NSArray, the object returned is still an NSMutableArray, and the mutable methods are defined for it. Declaring the property in this way does not prevent someone from accidentally mutating the array.
If you want to be sure that the returned array is not mutable, you could declare the property as in your original example, and then roll your own accessor:
- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }
Note that this would return an unretained NSArray. It would be up to the caller to take ownership of the object if it needed to persist.
You are seeing errors because XCode is now issuing warnings and errors for things it did not previously...
I would argue that it should be at most a warning to do what you are doing, I understand your attempt to present the array as immutable to the outside world but have it mutable inside the class. You may want to consider a different accessor with a different name, built to return the mutable array specifically.
It is still Objective-C 2.0; the compiler is just maybe a little updated with considering this kind of type changing an error. It pretty much should be an error. At least it should warn you that you likely don't mean what you wrote. Then you could cast stuff to make it not warn you, which you can't do with the #synthesize statement.
I just exactly pasted your code and a synthesize statement into my controller and I got no errors or warnings about it. It built fine. Now I set the base SDK to "Simulator 3.0", and the build to "Simulator 3.0 Debug". This project had started in the 2.2.1 SDK and I just installed the 3.0 SDK yesterday; Xcode is version 3.1.3.
Update: Oh I see that actually trying to set the property is where you get the error you mentioned.
self.myArray = [NSArray arrayWithObject:#"foo"];
Clearly you cannot #synthesize this behavior and must write your own accessors.
- (NSArray*)myArray {
return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
myArray = [NSMutableArray arrayWithArray:pMyArray];
}
Filling in these accessors, did not make the message go away, so I had to change the access to:
[self setMyArray:[NSArray arrayWithObject:#"foo"]];
Using the above syntax without custom accessors also did not work.
PS Wow, is anyone else annoyed that you can neither copy message bubbles, or the text in the build results window?
So this is really to do with the #synthesize call that is not happy about exposing a NSMutableArray as an NSArray - why not just implement the getMethod.
Actually thinking about it it must be the set method that is not happy - you wouldn't be able to set an NSArray into an NSMutableArray.
Your questions were:
Is anyone aware of changes to objective-c between OS 2.2.1 and 3.0?
Is there any documentation for these changes?
The definitive answers are:
1) There were no intentional changes to the language specification, but the compiler and other developer tools changed. Chris and his coworkers are the experts on those changes.
2) Probably not, because any changes were unintentional or made to better match behavior with the documentation.
You shouldn't be so quick to dismiss Chris' answer as "a guess." Chris works on Apple's developer tools. You might get another answer you like more, but you won't be getting a more expert answer.