3

Say I have the following function that returns a CLLocationCoordinate2D, which is just a struct that has two doubles (named longitude and latitude) in it:

- (CLLocationCoordinate2D)getCoordinateForHouse:(House *)house
{
    CLLocationCoordinate2D coordToReturn;
    coordToReturn.latitude = // get house's latitude somehow
    coordToReturn.longitude = // get house's longitude somehow

    return coordToReturn;
}

Can I basically treat this struct just like any other primitive type? For instance, if I call the function above in code somewhere else like this:

CLLocationCoordinate2D houseCoord = 
       [someClassThatTheAboveFunctionIsDefinedIn getCoordinatesForHouse:myHouse];

The value that was returned from the function is simply copied into houseCoord (just like any other primitive would act), right? I don't have to worry about the CLLocationCoordinate2D ever being destroyed elsewhere?

Seems obvious to me now that this is probably the case, but I just need confirmation.

jscs
  • 63,694
  • 13
  • 151
  • 195
Tim
  • 4,295
  • 9
  • 37
  • 49

3 Answers3

5

This is an area where Objective-C inherits its behaviour directly from C — assigning structs causes a shallow copy. So if you have any pointers inside the structs then you'll copy the pointer, not the thing pointed to. In C code you need to factor that in to your adhoc rules about ownership. In Objective-C the automatic reference counting compiler isn't capable of dealing with references to objects within structs (or, I think, unions) so it's smart not to become too attached to the idea in any event.

Tommy
  • 99,986
  • 12
  • 185
  • 204
1

You are correct. If you browse the documentation, you will see:

typedef double CLLocationDegrees;

typedef struct {
   CLLocationDegrees latitude;
   CLLocationDegrees longitude;
} CLLocationCoordinate2D;
titaniumdecoy
  • 18,900
  • 17
  • 96
  • 133
  • Yes, I saw that before, I guess my question was more about how structs work in general. Whether they can be treated exactly like primitives (except of course for being able to dot them and get different fields). – Tim Aug 05 '11 at 20:29
  • Yes, struct values should be treated like primitives. In certain cases you may need to perform manual memory management using malloc and free, but in that case you will have a pointer to the struct which is not the case here. – titaniumdecoy Aug 05 '11 at 20:31
  • ok cool, thank you. one quick followup: can structs ever have pointers in them? pointers are primitives, or are they? does it matter what the pointer points to as to whether it's considered a primitive? – Tim Aug 05 '11 at 20:33
  • Yes, structs can have pointers in them, in which case you would have to malloc and free the memory which that pointer references. Pointers themselves are primitives. A pointer just points to a block of memory which can contain anything--an int or another struct, for instance. – titaniumdecoy Aug 05 '11 at 20:38
  • 1
    `id` and `UIView *` are pointers to instances of NSObject. The pointers themselves are primitives; they point to (non-primitive) objects. Objects are essentially structs with special runtime support for associating a superclass and methods, etc. – titaniumdecoy Aug 05 '11 at 20:40
1

Yes, that is how you handle returning structures. When you use a method which returns a structure, the compiler modifies it so that it actually returns void, and adds a new first argument which is a pointer to the structure that the result should be stored in. So, your method is compiled more like this:

- (void):(CLLocationCoordinate2D*)returnValue getCoordinateForHouse:(House *)house
{
    CLLocationCoordinate2D coordToReturn;
    coordToReturn.latitude = // get house's latitude somehow
    coordToReturn.longitude = // get house's longitude somehow

    returnValue->latitude = coordToReturn.latitude;
    returnValue->longitude = coordToReturn.longitude;
}
ughoavgfhw
  • 39,734
  • 6
  • 101
  • 123
  • 1
    That method name is perfectly valid. The labels in method names can be empty strings. – jscs Aug 05 '11 at 21:03
  • 1
    @ughoavgfhw: I'm not questioning your assertion that Objective-C compiles methods returning structures into methods that take a pointer argument to a structure, but do you have a source? I was not aware of that behavior and would be interested to read more about it. – titaniumdecoy Aug 05 '11 at 21:26
  • 1
    See the docs for objc_msgSend_stret(): http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/objc_msgSend_stret . You can see that its first argument is a pointer to a block of memory large enough to contain the struct to be returned. The runtime passes the address of returnValue. – Rudy Velthuis Aug 05 '11 at 23:10