使用Objective-C Struct时,防止takeRetainedValue或takeUnretainedValue

时间:2016-06-26 15:31:47

标签: objective-c c swift memory-management automatic-ref-counting

我正在使用this approach将字符串常量保持在一起。使用该帖子中的相同示例:

MONExtResult.h

struct MONExtResultStruct {
    __unsafe_unretained NSString * const AppID;
    __unsafe_unretained NSString * const ErrorCode;
    __unsafe_unretained NSString * const Progress;
};

extern const struct MONExtResultStruct MONExtResult;

MONExtResult.m

const struct MONExtResultStruct MONExtResult = {
    .AppID = @"appid",
    .ErrorCode = @"errorcode",
    .Progress = @"progress"
};

这可以在Objective-C中使用,如下所示:

NSString *str = MONExtResult.AppID;

但是当我尝试在Swift中使用它时,

let appID: String = MONExtResult.AppID

...我收到错误:

  

无法转换'Unmanaged< NSString>!'类型的值预期的参数类型'String'

这是因为我需要从unmanaged wrapper中获取值,然后将其转换为字符串:

let appID: String = MONExtResult.AppID.takeUnretainedValue() as String

有没有办法对Objective-C代码进行注释,以防止需要像{C}函数takeUnretainedValueCF_IMPLICIT_BRIDGING_ENABLED一样调用CF_RETURNS_RETAINED

更新: Objective-C和Swift都必须可以访问常量。否则我只会使用带有String原始值的Swift枚举。

1 个答案:

答案 0 :(得分:0)

我能够构建的最接近的是:

enum MONExtResult: String {
    case AppID = "com.me.myapp"
    case ErrorCode = "game over"
    case Progress = "vote Tuesday"
}

extension String {
    init(const: MONExtResult) {
        self = const.rawValue
    }
}

let err = String(MONExtResult.ErrorCode)

值得注意的是,这不起作用:

let appID: String = MONExtResult.AppID

最后缺少.rawValue,但只要你愿意接受大致相同数量的字符和稍微不同的语法,我相信这就是你想到的。