will autorelease release my non-object c array? I am wondering, because perhaps only objects know their reference count? here's my code:
-(int *)getCombination{
int xIndex = arc4random() % [self._num1 count] + 1;
int yIndex = arc4random() % [self._num2 count] + 1;
int *combination;
combination[0] = [[self._num1 objectAtIndex:xIndex]intValue];
combination[1] = [[self._num2 objectAtIndex:yIndex]intValue];
return combination;
}
and this is my main() function:
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([YYAAppDelegate class]));
}
}
So is the autorelease working for objects only or will it release my c array from getCombination?
Edit: Since the answer is no, autorelease doesn't work for c arrays/pointers I used the following code which uses NSArrays instead:
#import <Foundation/Foundation.h>
@interface Multiplication : NSObject
@property (strong, nonatomic) NSMutableArray *_combinations;
-(id)initArrays;
-(NSArray *)getCombination;
@end
#import "Multiplication.h"
@implementation Multiplication
@synthesize _combinations;
-(void)initializeArray{
self._combinations = [[NSMutableArray alloc]init];
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
NSNumber *x = [NSNumber numberWithInt:i];
NSNumber *y = [NSNumber numberWithInt:j];
[self._combinations addObject:[NSArray arrayWithObjects:x, y, [NSNumber numberWithInt:([x intValue] * [y intValue])], nil]];
}
}
}
-(NSArray *)getCombination{
if ([self._combinations count] == 0) {
[self initializeArray];
}
int index = arc4random() % [self._combinations count];
NSArray *arr = [self._combinations objectAtIndex:index];
[self._combinations removeObjectAtIndex:index];
return arr;
}
-(id)initArrays{
self = [super init];
if (self) {
[self initializeArray];
}
return self;
}
@end
BTW this function is supposed to provide a method for randomly displaying every combination in the multiplication table of 10X10 and restart when all combinations have been displayed and equal number of times.
autorelease
is a message that can be sent to Objective C objects. Before ARC, you needed to do it explicitly, like this:
MyObject *obj = [[[MyObject alloc] init] autorelease];
Under ARC, the compiler figures out the autorelease
part for you, but the message is stil sent to the object; that object gets added to the autorelease pool as a result. When autorelease pool gets drained, all objects inside it are sent a release
message. If there are no other references to the object, its reference count drops to zero, and the object get cleaned up.
C arrays do not respond to autorelease
or release
message: they are not Objective C entities, so they do not respond to messages at all. Therefore, you must deal with the memory that you allocate for these arrays manually, by calling malloc
1 and free
.
Of course you can place autoreleased objects inside a C array, and these objects will be cleaned up in the regular course of action. For example
NSNumber **numbers = malloc(2, sizeof(NSNumber*));
numbers[0] = [NSNumber numberWithInt:123];
numbers[1] = [NSNumber numberWithInt:456];
return numbers;
If the caller does not retain
NSNumber
objects inside the numbers
array, these objects will be autoreleased2. The numbers
object, however, needs to be cleaned up separately:
free(numbers);
malloc
in your code, so accessing combinatopn[...]
is undefined behavior.
2 Causing hanging references in the process.