【发布时间】:2011-11-18 23:19:18
【问题描述】:
我已经阅读了很多帖子,并且对为什么这是一个问题感到困惑 - ARC 不应该处理这个问题吗?
利用下面的回复,我能够将问题隔离为“Moves”作为罪魁祸首——它似乎永远不会被释放并继续消耗内存,即使它被设置为 nil。 Moves 设置在 Grid.m 底部的两个位置 - 方法 FindRandomMove 并在 recursiveProcess 例程中调用。
一般结构是由列组成的网格,由单元组成。单元格值是随机生成的以制作拼图。多次这样做是为了测试谜题解决方案。
程序首先在 Grid.m 中运行 generateTest
(如果我做的事情没有遵循最佳实践,或者有更好/正确的方法,我感谢代码任何部分的所有 cmets。
完整的测试代码如下:
Cell.h
@interface Cell : NSObject {
CFMutableBitVectorRef _validNumbersBitVector;
NSUInteger _answerNumber;
UIColor * _color;
NSUInteger _cellRow;
NSUInteger _cellCol;
}
@property CFMutableBitVectorRef validNumbersBitVector;
@property NSUInteger answerNumber;
@property (nonatomic, strong) UIColor * color;
@property NSUInteger cellRow;
@property NSUInteger cellCol;
//设置方法
- (void) setValid: (BOOL)valid number:(NSUInteger)numberToChange;
- (void) setAllNumbersToValidState:(BOOL) valid;
// get methods
- (BOOL) numberIsValid: (NSUInteger)numberToCheck;
- (NSUInteger) getRandomValidNumber;
- (NSUInteger) validNumberCount;
@end
Cell.m
#import "Cell.h"
#define RANGE CFRangeMake(0,9)
@implementation Cell
@synthesize validNumbersBitVector = _validNumbersBitVector;
@synthesize answerNumber = _answerNumber;
@synthesize color = _color;
@synthesize cellRow = _cellRow;
@synthesize cellCol = _cellCol;
-(id) init {
if ((self = [super init])){
_answerNumber = 0;
_validNumbersBitVector =CFBitVectorCreateMutable(NULL,10);
}
return self;
}
- (void) setValid:(BOOL)valid number:(NSUInteger)numberToChange {
CFBitVectorSetBitAtIndex(self.validNumbersBitVector, numberToChange - 1, !valid);
}
-(void) setAllNumbersToValidState:(BOOL) valid{
CFBitVectorSetBits(self.validNumbersBitVector, RANGE, !valid);
}
-(NSUInteger) validNumberCount{
return CFBitVectorGetCountOfBit(self.validNumbersBitVector, RANGE, 0);
}
- (BOOL) numberIsValid: (NSUInteger)numberToCheck{
return !CFBitVectorGetBitAtIndex(self.validNumbersBitVector, numberToCheck - 1);
}
- (NSUInteger) getRandomValidNumber{
NSUInteger pos;
NSUInteger counter = 0;
NSUInteger number = 0;
NSUInteger validCount = 0;
validCount = CFBitVectorGetCountOfBit(self.validNumbersBitVector, RANGE, 0);
if (validCount > 0) {
pos = (rand() %(validCount)) + 1;
while (counter < pos){
number ++;
if (!CFBitVectorGetBitAtIndex(self.validNumbersBitVector, number - 1) ) {
counter ++;
}
}
}
return number;
}
@end
Moves.h
#import "Cell.h"
@interface Moves : NSObject {
NSUInteger _row;
NSUInteger _col;
NSUInteger _newValue;
Cell * _cell;
}
@property NSUInteger row;
@property NSUInteger col;
@property NSUInteger newValue;
@property (nonatomic,retain) Cell * cell;
@end
移动.m
#import "Moves.h"
@implementation Moves
@synthesize row = _row;
@synthesize col = _col;
@synthesize newValue = _newValue;
@synthesize cell = _cell;
-(id) init {
if ((self = [super init])) {
_row = 0;
_col = 0;
_newValue = 0;
}
return self;
}
@end
网格.h
#import "Col.h"
#import "Moves.h"
@interface Grid : NSObject {
NSMutableArray* _rowData;
NSMutableArray* _emptyCells;
BOOL _puzzleSolved;
BOOL _bruteForceEnd;
}
@property (nonatomic, retain) NSMutableArray * rowData;
@property (nonatomic, retain) NSMutableArray * emptyCells;
@property BOOL puzzleSolved;
@property BOOL bruteForceEnd;
- (void) generateTest;
- (void) initializePuzzle;
- (Cell *) cellAtRow:(NSUInteger) pRow andCol:(NSUInteger) pCol;
- (void) setAnswerNumber:(NSUInteger)newAnswerNumber cell:(Cell *) pCell;
- (Moves*) FindRandomMove;
- (NSUInteger) recursiveProcess:(NSUInteger)BFCount;
@end
网格.m
#import "Grid.h"
#import <QuartzCore/QuartzCore.h>
@implementation Grid
@synthesize rowData = _rowData;
@synthesize emptyCells = _emptyCells;
@synthesize puzzleSolved = _puzzleSolved;
@synthesize bruteForceEnd = _bruteForceEnd;
- (id) init
{
if ((self = [super init])) {
_rowData = [[NSMutableArray alloc] initWithCapacity:10];
_emptyCells = [[NSMutableArray alloc] init];
NSUInteger i;
for (i = 0; i<9; i++) {
Col *tmpCol = [[Col alloc] initWithRow:i + 1];
[_rowData addObject:tmpCol];
}
}
return self;
}
- (void) generateTest {
for (int mloop2 = 1; mloop2 < 10000;mloop2 ++) {
for (int mloop = 0; mloop < 1000; mloop ++) {
[self initializePuzzle];
[self recursiveProcess:0];
}
}
}
- (void) initializePuzzle{
self.bruteForceEnd = NO;
[self.emptyCells removeAllObjects];
for (Col * tmpCol in self.rowData){
for (Cell * answerCell in tmpCol.colData){
answerCell.answerNumber = 0;
[self.emptyCells addObject:answerCell];
}
}
}
- (Cell *) cellAtRow:(NSUInteger) pRow andCol:(NSUInteger) pCol {
Cell * tmpCell;
tmpCell = [[self.rowData objectAtIndex:pRow - 1] cellAtCol:pCol];
return tmpCell;
tmpCell = nil;
}
- (void) setAnswerNumber:(NSUInteger)newAnswerNumber cell:(Cell *) pCell{
if (pCell.answerNumber != newAnswerNumber) {
if (newAnswerNumber == 0 ) [self.emptyCells addObject: pCell];
if (pCell.answerNumber == 0) [self.emptyCells removeObject:pCell];
pCell.answerNumber = newAnswerNumber;
}
pCell = nil;
}
- (NSUInteger) recursiveProcess:(NSUInteger)BFCount{
Moves * nextMove;
Cell * answerCell;
NSUInteger counter;
NSUInteger number;
NSUInteger row;
NSUInteger col;
BFCount ++;
nextMove = [self FindRandomMove];
number = nextMove.newValue;
row = nextMove.row;
col = nextMove.col;
nextMove = nil;
answerCell = [self cellAtRow:row andCol:col];
[self setAnswerNumber:number cell:answerCell];
answerCell = nil;
if (BFCount > 48) self.bruteForceEnd=YES;
if (self.puzzleSolved) self.bruteForceEnd = YES;
if (self.bruteForceEnd) return BFCount;
counter = [self recursiveProcess:BFCount]; // try again
if (counter > 50) NSLog(@"brute force 50");
return BFCount;
}
- (Moves *) FindRandomMove{
Moves * tMove =[[Moves alloc] init];
NSUInteger col = 0;
NSUInteger row = 0;
NSUInteger possibleCount = 0;
NSMutableArray * possibleCells = [[NSMutableArray alloc] initWithCapacity:82];
NSUInteger selectedPossible;
NSUInteger numberToUse = 0;
Cell * answerCell ;
NSUInteger validCount = 0;
for ( Cell * tmpCell in self.emptyCells){
validCount=tmpCell.validNumberCount;
[possibleCells addObject:tmpCell];
possibleCount ++;
}
if (possibleCount != 0){
selectedPossible = 0;
if (possibleCount > 1) selectedPossible = rand() % (possibleCount - 1);
answerCell = [possibleCells objectAtIndex:selectedPossible];
row = answerCell.cellRow;
col = answerCell.cellCol;
numberToUse = answerCell.getRandomValidNumber;
answerCell = nil;
}
possibleCells = nil;
tMove.row = row;
tMove.col = col;
tMove.newValue = numberToUse;
return tMove;
}
@end
【问题讨论】:
标签: objective-c cocoa-touch nsmutablearray automatic-ref-counting