13

I'm new to Objective C

I tried using a simple struct and got

arc forbids objective-c objects in struct

Looking up ARC, it looks like this is the specification that defines Objective C syntaxt - is that correct?

Secondly, how do I go about using struct if it's not allowed?

Thank you!

Edit: Some code as a sample

@implementation Cities {
    // The goal is to have a struct that holds information about a city,
    // like when a person started and ended living there.
    // I was trying to make this struct an instance variable of the Cities
    // class
    // XCode doesn't like the below struct definition

    struct City
    {
        NSString *name;
        int *_startYear;
        int *_endYear;
    };
}
user2490003
  • 10,706
  • 17
  • 79
  • 155
  • Show the code, why do you want a struct? – Wain Feb 12 '15 at 07:39
  • No particular reason right now, I'm just playing around with code samples and wondering why I get the above error when using a `struct`. If it's not advisable to use, that's fine, I won't use it long term. I'm more interested in *why* it's throwing that error. Thanks! – user2490003 Feb 12 '15 at 07:43
  • I don't remember the exact reason, you can use structs just don't put pointers to class instances in them. – Wain Feb 12 '15 at 07:45
  • The ARC document is _not_ the Objective-C specification. [There is, unfortunately, no such specification](http://stackoverflow.com/a/11007768/). – jscs Feb 12 '15 at 19:48
  • Closely related: [Fixing ARC error when using ObjC object in struct](http://stackoverflow.com/q/14784973) – jscs Feb 12 '15 at 19:49

3 Answers3

22

arc forbids objective-c objects in struct

Structs are a C construct. The compiler is telling you, in very unambiguous terms, that you can't have Objective-C objects inside a struct, not that structs are illegal.

You can use regular C structs all you want.

Your example tries to put references to an Objective-C object, NSString, into a struct, which is incompatible with ARC.

Structs are typically used for simple data structures. Examples that you are likely to come across in Objective-C code are CGPoint and CGRect.

CGPoint looks something like this

struct CGPoint 
{ 
   CGFloat x; 
   CGFloat y; 
};

A CGFloat is, I think, just a double, and the idea is to represent a point in 2D space. Structs can include pointers to other structs, C-arrays, and standard C data types such as int, char, float... And Objective-C classes can contain structs, but the reverse does not work.

Structs can also get pretty complicated, but that is a very broad topic that is best researched using Google.

rptwsthi
  • 10,094
  • 10
  • 68
  • 109
dandan78
  • 13,328
  • 13
  • 64
  • 78
  • Mind elaborating what a regular C struct is? I'm not familiar with C as well :) I did add a code snippet to the question though, if that helps to see what I was trying to do. Thanks! – user2490003 Feb 12 '15 at 07:51
  • That makes sense! One more thing - and sorry for being dense here - I get that Objective C objects can not be in a struct, and so my NSString definition is invalid. But your struct contains CGFloat - is that not an Objective C object? – user2490003 Feb 13 '15 at 20:50
  • CGFloat is just a typedef for float_32 i think, not sure – Bhargav Aug 10 '16 at 10:48
  • 1
    This response is outdated. As of WWDC '18, you are now allowed to specify ARC object pointers in C structs. – Daniel J Mar 10 '19 at 02:24
14

You can use struct in Objective-C++ with ARC in any case.

#import <Foundation/Foundation.h>

@interface City : NSObject
struct Data {
    NSString *name;
};

@property struct Data data;
@end

@implementation City
@end

int main()
{
    City *city = [[City alloc] init];
    city.data = (struct Data){@"San Francisco"};
    NSLog(@"%@", city.data.name);
    return 0;
}

If you compile it as Objective-C, you failed as you said.

$ clang -x objective-c -fobjc-arc a.m -framework Foundation 
a.m:5:15: error: ARC forbids Objective-C objects in struct
    NSString *name;
              ^
1 error generated.

Because C struct doesn't have the capability of management for variable life span.

But in C++, struct does have destructor function. So C++ struct is compatible with ARC.

$ clang++ -x objective-c++ -fobjc-arc a.m -framework Foundation
$ ./a.out
San Francisco
Kazuki Sakamoto
  • 13,929
  • 2
  • 34
  • 96
8

If you want to use struct in Objective C ( with ARC) use "__unsafe_unretained" attribute.

struct Address {
   __unsafe_unretained NSString *city;
   __unsafe_unretained NSString *state;
   __unsafe_unretained NSString *locality;
};
Soumen
  • 2,070
  • 21
  • 25
  • 3
    For those using this, be aware that accessing `__unsafe_unretained` variables that have been released will cause a crash – Alec O Mar 12 '18 at 17:40