我正在将一些旧的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时声明方法?
答案 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
,快速枚举等。