如何将其转换为 ARC

How to convert this to ARC

我正在将一些旧的 Obj-C 代码转换为 ARC。我有这个方法:

+ (NSString **)sortKeys
{
    return sortKeys;
}

而我对自动转换的投诉是:

Cannot initialize return object of type 'NSString *__autoreleasing *' with an lvalue of type 'NSString *__strong [14]

排序键声明为:

static NSString *sortKeys[] = {
NAME_KEY,
CATNUM_KEY,
CATNUM_NAME_KEY,
MAG_KEY,
DISTANCE_KEY,
CONST_KEY,
RISE_KEY,
TRANSIT_KEY,
SET_KEY,
RA_KEY,
DEC_KEY,
AZM_KEY,
ALT_KEY,
DATE_KEY
};

打电话也有投诉:

    NSString **sortKeys = [ListMgr sortKeys];

我不想转让字符串的任何所有权,我只是希望调用者能够遍历它们。

使用ARC时如何声明方法?

这与 ARC 不兼容。它不能安全地进行内存管理。您依赖于未承诺的行为(因此这一直是不安全的)。 sortKeys 未保留 NAME_KEY,因此无法保证 NAME_KEY 有效。你可能碰巧知道它会是什么(因为 NAME_KEY 例如是一个静态字符串),但这是一个实现细节,而不是语言承诺。 ARC 是关于保证,而不是 "we happen to get away with it."

正确的工具是 NSArray:

@interface MyClass : NSObject
+ (NSArray<NSString *>*)sortKeys;
@end

@implementation MyClass

static NSArray<NSString *>* sortKeys;

+ (void)initialize {
    if (self == [MyClass class] ) {
        sortKeys = @[ ... ];
    }
}

+ (NSArray<NSString *>*)sortKeys
{
    return sortKeys;
}

@end

如果您无法更改界面,则必须将此定义保留在非 ARC 文件中。

我将你的缓存保留在这里,但如果你不经常调用 +sortKeys,我会去掉 static,每次只构造一个新数组。它非常便宜,尤其是在这种情况下:

@interface MyClass : NSObject
+ (NSArray<NSString *>*)sortKeys;
@end

@implementation MyClass

+ (NSArray<NSString *>*)sortKeys
{
    return @[...]; // Just put your value here; then it's simple
}

@end

您可以使用 NSArrayinitWithObjects:count: 初始化器将 C 数组转换为 Foundation 数组,并创建一个 ARC,内存安全数组:

+ (NSArray<NSString *> *)sortKeys
{
    static NSArray<NSString *> *convertedKeys;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        convertedKeys = [[NSArray alloc] initWithObjects:sortKeys count:sizeof(sortKeys)];
    });
    return convertedKeys;
}

您将获得与 ARC 兼容的代码,并且您还可以访问 NSArray 的辅助方法 - 如 count、快速枚举等