【问题标题】:Does Objective-C forbid use of structs?Objective-C 是否禁止使用结构?
【发布时间】:2015-02-12 07:38:20
【问题描述】:

我是 Objective C 的新手

我尝试使用简单的struct 并得到了

arc forbids objective-c objects in struct

Looking up ARC,看起来这是定义 Objective C 语法的规范 - 对吗?

其次,如果不允许,我该如何使用struct

谢谢!

编辑:一些代码作为示例

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

【问题讨论】:

  • 显示代码,为什么要结构体?
  • 目前没有特别的原因,我只是在玩代码示例,想知道为什么在使用struct 时会出现上述错误。如果不建议使用,那很好,我不会长期使用它。我对 为什么 它会抛出该错误更感兴趣。谢谢!
  • 我不记得确切的原因,你可以使用结构,只是不要在其中放置指向类实例的指针。
  • ARC 文档不是 Objective-C 规范。 There is, unfortunately, no such specification.

标签: objective-c struct automatic-ref-counting


【解决方案1】:

arc 禁止 objective-c 对象 in struct

结构是一个 C 结构。编译器用非常明确的术语告诉你,你不能在结构中包含 Objective-C 对象,而不是结构是非法的。

您可以随心所欲地使用常规的 C 结构。

您的示例尝试将对 Objective-C 对象 NSString 的引用放入与 ARC 不兼容的 struct

结构通常用于简单的数据结构。您可能在 Objective-C 代码中遇到的示例是 CGPointCGRect

CGPoint 看起来像这样

struct CGPoint 
{ 
   CGFloat x; 
   CGFloat y; 
};

我认为CGFloat 只是一个double,它代表二维空间中的一个点的想法。结构体可以包含指向其他结构体、C 数组和标准 C 数据类型的指针,例如 intcharfloat... 而 Objective-C 类可以包含结构体,但反过来就不行。

结构也可能变得相当复杂,但这是一个非常广泛的主题,最好使用 Google 进行研究。

【讨论】:

  • 介意详细说明什么是常规 C 结构吗?我也不熟悉C :) 我确实在问题中添加了一个代码sn-p,如果这有助于了解我想要做什么。谢谢!
  • 有道理!还有一件事 - 很抱歉在这里很密集 - 我知道 Objective C 对象不能在一个结构中,所以我的 NSString 定义是无效的。但是您的结构包含 CGFloat - 这不是 Objective C 对象吗?
  • CGFloat 只是我认为 float_32 的 typedef,不确定
  • 此响应已过时。从 WWDC '18 开始,您现在可以在 C 结构中指定 ARC 对象指针。
【解决方案2】:

在任何情况下,您都可以在 Objective-C++ 中将 struct 与 ARC 一起使用。

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

如果你把它编译成Objective-C,你就失败了。

$ 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.

因为C struct 不具备可变寿命的管理能力。

但在 C++ 中,struct 确实具有析构函数。所以 C++ struct 与 ARC 兼容。

$ clang++ -x objective-c++ -fobjc-arc a.m -framework Foundation
$ ./a.out
San Francisco

【讨论】:

    【解决方案3】:

    如果您想在 Objective C 中使用 struct(带有 ARC),请使用“__unsafe_unretained”属性。

    struct Address {
       __unsafe_unretained NSString *city;
       __unsafe_unretained NSString *state;
       __unsafe_unretained NSString *locality;
    };
    

    【讨论】:

    • 使用这个的人请注意,访问__unsafe_unretained已经释放的变量会导致崩溃
    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    相关资源
    最近更新 更多