【问题标题】:How to initialize an Objective-C struct in constructor?如何在构造函数中初始化 Objective-C 结构?
【发布时间】:2012-09-17 07:33:48
【问题描述】:

我在 Objective-C 上使用结构来存储一些数据,如下所示:

@interface Interface : NSObject
{
    // my Data
    struct Data
    {
        __unsafe_unretained BOOL isInit;
        __unsafe_unretained BOOL isRegister;
        __unsafe_unretained NSString* myValue;
        
       // Data() : isInit(false), isRegister(false), myValue(@"mYv4lue") {} // Constructor doesnt work
    };

    struct Data myData;  // Create Struct
}

但我无法使用构造函数进行编译。我希望在创建结构时这些值采用一些默认值。

我该怎么做?

【问题讨论】:

  • 我很谨慎,我需要在启动某些操作时正确初始化值并且我不希望出现故障
  • 这个结构体有什么原因不能转换成简单的类吗?
  • __unsafe_unretained 不适用于 BOOLs -- 它们是基元,而不是对象。

标签: objective-c struct constructor initialization


【解决方案1】:

结构没有初始化器,如果你想创建一个具有一组特定值的结构,你可以编写一个返回的函数为你创建并初始化它:

例如

struct Data {
        BOOL isInit;
        BOOL isRegister;
        NSString* myValue;
};

Data MakeInitialData () {
    data Data;
    data.isInit = NO;
    data.isRegister = NO;
    data.myValue = @"mYv4lue";

    return data;
}

现在您可以通过以下方式获得正确设置的结构:

Data newData = MakeInitialData();

不过,请注意;您似乎正在使用 ARC,它不适用于其中包含对象指针的结构。在这种情况下,建议只使用类而不是结构。

【讨论】:

  • 您可能要提到这段代码是 Swift,而不是 Objective-c。就目前而言,该示例不会将“数据”作为 Objective-c 中的局部变量提供给您。 Pritesh Kadam 的回答更加优雅和全面。
  • 公平地说,它是 Objective-C,因为 Swift 在 2012 年或 2014 年都不存在。而且这甚至不会在 Swift 中编译,因为 Data 是 Foundation 中定义的类型。
  • @JoshCaswell 当我说代码是 Swift 时,我确实在猜测,至于 Pritesh Kadam 的回答:我不是我在想的,我发誓要修改我的 Swift 调用方式。然而,我非常确定这段代码不是有效的 Objective-C。还有 Abizern:“数据是 Foundation 中定义的类型”?哪个基金会?不是 NextStep 的。
  • @ElisevanLooij Data 是一个连接到NSData developer.apple.com/documentation/foundation/data 的值类型
  • 对。看,这就是重点:如果您查看该链接的页面顶部,您会看到“Language:Swift”。它不是一个下拉菜单,允许一个 Objective-C 的选项,它与 Swift 相关联。因此,在我从未使用过 Swift 的 Xcode 版本 9.2 (9C40b) 安装中,Data 是一种未知类型,会导致编译器错误“Unknown type name 'Data'”。
【解决方案2】:

您可以使用静态对象进行默认设置,如下所示初始化结构。

typedef struct
{
    BOOL isInit;
    BOOL isRegister;
    __unsafe_unretained NSString* myValue;

} Data;
static Data dataInit = { .isInit = NO, .isRegister = NO, .myValue = @"mYv4lue"};

Data myCopyOfDataInitialized = dataInit;

【讨论】:

    【解决方案3】:

    您正在执行此操作的空间(在类的 @interface 块开头的大括号之间)不允许运行代码。它仅用于 ivars 的声明。你真的不应该在那里声明structs(我很惊讶编译)。

    将构造函数调用移至类的init 方法。这就是在 ObjC 中应该进行 ivars 初始化的地方。

    【讨论】:

    • 设置 ivar 最好在初始化中完成,因为初始化保证在对象的生命周期中只被调用一次。
    • 你说的是+initializeclass 方法,@ElisevanLooij?每个 class 调用一次,而不是每个 _instance。此外,您无法访问其中的实例变量,因为没有该类的实例。
    • -init 的返回类型是idinstancetype,而不是void
    • 不错的忍者编辑。 :/ ...我在第二段中推荐使用init。那我们在说什么?
    【解决方案4】:

    你也可以这样做:

    @interface Interface : NSObject
    {
    
       typedef struct tagData
    
        {
            __unsafe_unretained BOOL isInit;
            __unsafe_unretained BOOL isRegister;
            __unsafe_unretained NSString* myValue;
    
            tagData(){
               isInit = NO;
               isRegister = NO;
               myValue = NULL;
            }
        } myData;
    
    }
    

    【讨论】:

    • 很遗憾,这段代码甚至无法在 Objective-C 中编译。
    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2020-10-04
    • 2018-06-30
    • 2011-01-06
    相关资源
    最近更新 更多