如何将其转换为 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
您可以使用 NSArray
的 initWithObjects: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
、快速枚举等
我正在将一些旧的 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
您可以使用 NSArray
的 initWithObjects: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
、快速枚举等