3

This question uses CLLocationCoordinate2D as an example, but this applies to other structs as well, such as CGPoint (although ones like those are usually automatically included).

I want to use CLLocationCoordinate2D as a return value in a class method. If it were an object you could write the following at the top and it would be fine, as long as the .m file had a reference to CoreLocation.h

@class ClassName

Is there an equivalent way of telling the compiler not to worry about the struct without re-declaring it or importing the header file into the class' header file?

I do not want to import CoreLocation.h into the header file, since that would mean every file that imports that header file would inherit CoreLocation.

Thanks

shim
  • 9,289
  • 12
  • 69
  • 108

4 Answers4

2

I'm not totally getting the point why you do not want to import CoreLocation, but CLLocationCoordinate2D is declared in CoreLocation.h. I'm not aware about a method like @class for struct and I don't think it exists since struct are C types.
What you can do is create your own class that wraps the CLLocationCoordinate2D or return the NSValue from it, or (why not?) a dictionary.

Andrea
  • 26,120
  • 10
  • 85
  • 131
  • If my header file is going to be used throughout the application, I don't want to import CoreLocation into every single file that imports this header file. It's standard practice to avoid importing headers into header files. I ended up just switching to use CLLocation* anyhow. – shim Jul 18 '13 at 16:44
1

Easiest way to do this is to just use an object instead of the struct, then you can use the @class keyword. In this case, the CLLocation object works just fine. Alternatively you can often use an NSDictionary in place of a struct, but an object is a bit easier to manage.

shim
  • 9,289
  • 12
  • 69
  • 108
  • 1
    An Objective-C object is not a struct. It is actually a _pointer_ to a struct. This is not an appropriate answer to your original question where you want C structs as return type. – CouchDeveloper Jul 18 '13 at 18:25
  • Yeah, but it accomplishes the same thing. No real reason to force yourself to go through all the trouble of dealing with the structs when you can just use an object. Sure it doesn't solve the issue, but since there is no "@class" for structs, then it's simpler to just use @class if you can (and generally you can when it comes to Objective C and iOS frameworks). – shim Jul 19 '13 at 02:22
0

There is no straightforward way of doing that with single keyword.

Here you can find why it is not straightforward, although it is stated that it is not possible to do that, somewhat true but not completely. Forward declare a struct in Objective-C

And here is the workaround of doing this Forward declare structs in Objective C

Hope this will help.

Community
  • 1
  • 1
kyurkchyan
  • 2,260
  • 2
  • 23
  • 37
  • "And here is the workaround of doing this" That does not help. It is about dealing with a pointer to a struct, not a struct itself. – newacct Jul 19 '13 at 21:52
0

You return a struct like any other type. But you should be aware that when returning a struct you are returning a copy of the internal value on the stack as a temporary variable. Unlike an Objective-C object where you are actually returning a pointer.

The type you return MUST be a complete type. That means, in your method declaration you need the definition of the struct. In your case, that means, you need to include the header.

For example:

typedef struct MyStruct {
    int a;
    int b;
} MyStruct;

@interface MyClass : NSObject
+(MyStruct) theStruct;
@end
@implementation MyClass
+(MyStruct) theStruct {
    MyStruct s = {.a = 1, .b = 2};
    return s;
}
@end


int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyStruct s1 = [MyClass theStruct];
        s1.a = 100;
        s1.b = 100;           
        NSLog(@"s1 = {%d, %d}", s1.a, s1.b);            
        NSLog(@"MyStruct.theStruct = {%d, %d}", [MyClass theStruct].a, [MyClass theStruct].b);            

        [MyClass theStruct].a = 0;   // has no effect!            
    }
    return 0;
}

Prints:

s1 = {100, 100}
MyStruct.theStruct = {1, 2}
CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
  • This does not answer the question. I want to use Apple's struct, not redefine it in my code. – shim Jul 18 '13 at 16:39
  • 1
    It does answer your question, and it explains the reason why you need the definition of the struct and that a forward declaration is not sufficient. Just use whatever struct in your code and include the header which contains the corresponding definition (as explained). You don't redefine it that way. – CouchDeveloper Jul 18 '13 at 18:07