Does Objective-C forbid use of structs?

2020-07-06 02:09发布

问题:

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;
    };
}

回答1:

arc forbids objective-c objects in struct

Structs are a C construct. The compiler is telling you, in very unabiguous 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 it 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.



回答2:

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


回答3:

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;
};