Objective C 指向原始类型的指针
Objective C pointers to primitive types
我来自 java 背景,我想知道是否翻译以下 java 代码:
public class SomeClass {
private int[] someArray;
//+....other instance variables
public SomeClass(int arraySize) {
this.someArray = new int[arraySize];
//some other initialization
}
}
可以安全地转换为 Objective C,如下所示:
@implementation SomeClass
{
int *_myArray;
//some other private fields...
}
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
int newArray[arraySize];
_myArray = newArray;
//some other initializations
}
return self;
}
}
我显然知道 NSArray 和 NSNumber 装箱,但上面的代码听起来更清晰、更高效,特别是我的应用程序在某些情况下需要保存对 SomeClass 的数千个引用。同时我不确定原始指针是否可以安全地用于 ARC 以及它们是否会导致泄漏。
我已经尝试了以下虚拟测试以查看是否会按预期工作:
@implementation SomeClassTests
{
int *_myArray;
//some other private fields...
}
- (void)testExample {
int array[] = {4, 2, 1, 0};
_myArray = array;
[self changeArray:_myArray];
XCTAssertEqual(_myArray[0], -1);
XCTAssertEqual(_myArray[1], -1);
XCTAssertEqual(_myArray[2], 1);
}
-(void)changeArray:(int *)array
{
array[1] = -1;
array[0] = -1;
}
}
考试通过了,但我还是没有信心。
任何想法指导将不胜感激。
在 Java 代码示例中,您在堆中分配内存,但在 Objective C 代码示例中,您在堆栈中分配内存。
这是在堆中分配的变体:
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
_myArray = malloc(arraySize * sizeof(int));
//some other initializations
}
return self;
}
- (void)dealloc {
if (_myArray != NULL) {
free(_myArray);
}
}
当您在堆栈上分配 newArray
并将指针传递给实例变量 someArray
时,您的实现将导致严重错误,但是一旦该方法 returns 堆栈将已恢复,使 someArray
成为悬空指针。
在 Objective-C 中使用 NSArray
个 NSNumber
个对象更为正常。如果要创建一个可以在初始化后添加或修改的数组,请使用 NSMutableArray
:
@implementation SomeClass
{
NSMutableArray *_someArray;
}
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
_someArray = [[NSMutableArray alloc] initWithCapacity:arraySize];
}
return self;
}
我来自 java 背景,我想知道是否翻译以下 java 代码:
public class SomeClass {
private int[] someArray;
//+....other instance variables
public SomeClass(int arraySize) {
this.someArray = new int[arraySize];
//some other initialization
}
}
可以安全地转换为 Objective C,如下所示:
@implementation SomeClass
{
int *_myArray;
//some other private fields...
}
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
int newArray[arraySize];
_myArray = newArray;
//some other initializations
}
return self;
}
}
我显然知道 NSArray 和 NSNumber 装箱,但上面的代码听起来更清晰、更高效,特别是我的应用程序在某些情况下需要保存对 SomeClass 的数千个引用。同时我不确定原始指针是否可以安全地用于 ARC 以及它们是否会导致泄漏。
我已经尝试了以下虚拟测试以查看是否会按预期工作:
@implementation SomeClassTests
{
int *_myArray;
//some other private fields...
}
- (void)testExample {
int array[] = {4, 2, 1, 0};
_myArray = array;
[self changeArray:_myArray];
XCTAssertEqual(_myArray[0], -1);
XCTAssertEqual(_myArray[1], -1);
XCTAssertEqual(_myArray[2], 1);
}
-(void)changeArray:(int *)array
{
array[1] = -1;
array[0] = -1;
}
}
考试通过了,但我还是没有信心。
任何想法指导将不胜感激。
在 Java 代码示例中,您在堆中分配内存,但在 Objective C 代码示例中,您在堆栈中分配内存。
这是在堆中分配的变体:
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
_myArray = malloc(arraySize * sizeof(int));
//some other initializations
}
return self;
}
- (void)dealloc {
if (_myArray != NULL) {
free(_myArray);
}
}
当您在堆栈上分配 newArray
并将指针传递给实例变量 someArray
时,您的实现将导致严重错误,但是一旦该方法 returns 堆栈将已恢复,使 someArray
成为悬空指针。
在 Objective-C 中使用 NSArray
个 NSNumber
个对象更为正常。如果要创建一个可以在初始化后添加或修改的数组,请使用 NSMutableArray
:
@implementation SomeClass
{
NSMutableArray *_someArray;
}
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
_someArray = [[NSMutableArray alloc] initWithCapacity:arraySize];
}
return self;
}