如何将其转换为ARC

时间:2016-12-08 18:14:42

标签: objective-c automatic-ref-counting

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

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

我从自动转换中获得的投诉是:

  

无法使用类型为'NSString * __ strong [14]

的左值初始化'NSString * __ autoreleasing *'类型的返回对象

sortKeys声明为:

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时声明方法?

2 个答案:

答案 0 :(得分:0)

这与ARC不兼容。它无法安全地对内存进行管理。你依赖的是未承诺的行为(所以这一直是不安全的)。 sortKeys未保留NAME_KEY,因此无法保证NAME_KEY有效。您可能碰巧会有特殊的知识(因为NAME_KEY是一个静态字符串),但这是一个实现细节,而不是语言承诺。 ARC是关于保证,而不是“我们恰好逃脱了它。”

正确的工具是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

答案 1 :(得分:0)

您可以使用NSArray的{​​{1}}初始化程序将initWithObjects:count:数组转换为C数组,并创建一个ARC,内存安全的数组:

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; } 的帮助程序方法 - 例如NSArray,快速枚举等。