Reputation: 699
I came from a java background and I'm trying to figure out if translating the following piece of java code:
public class SomeClass {
private int[] someArray;
//+....other instance variables
public SomeClass(int arraySize) {
this.someArray = new int[arraySize];
//some other initialization
}
}
could be safely translated to Objective C as follows:
@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;
}
}
I'm obviously aware of NSArray and NSNumber boxing but the above code sounds cleaner and more efficient, specially that my app will need at some cases to hold thousands of references to SomeClass. At the same time I'm not sure if primitive pointers are safe to use with ARC and whether they could cause leaks.
I've tried the following dummy test to see if things would work as expected:
@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;
}
}
The test passed, but I'm still not feeling really confident.
Any thoughts guidance would be highly appreciated.
Upvotes: 1
Views: 376
Reputation: 122401
Your implementation will lead to serious errors as you allocate newArray
on the stack and pass a pointer to the instance variable someArray
, however once that method returns the stack will be recovered, making the someArray
a dangling pointer.
It's more normal in Objective-C to use an NSArray
of NSNumber
objects for this. If you want to create an array that can be added to after initialization, and otherwise modified, then use an NSMutableArray
:
@implementation SomeClass
{
NSMutableArray *_someArray;
}
-(instancetype)initWithArraySize:(int)arraySize
{
if(self = [super init]) {
_someArray = [[NSMutableArray alloc] initWithCapacity:arraySize];
}
return self;
}
Upvotes: 1
Reputation: 13302
In Java code sample you allocate memory in Heap, but in Objective C code sample you allocate memory in Stack.
Here is variant with allocation in Heap:
-(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);
}
}
Upvotes: 1