This is not an answer. Just a response to "Post your code". Hope it wont be too long.
viewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "BGTangramClues.h";
#import "BGTangramLevel.h";
@interface compactTangramViewController : UIViewController
{
//The level.
BGTangramLevel *currentLevel;
int levelStepper;
}
//It is to be just a reference, therefore I use assign here.
@property (nonatomic, assign) BGTangramLevel *currentLevel;
-(void) notificationHandler: (NSNotification*) notification;
-(void) finishedCurrentLevel;
@end
viewController.m
#import "compactTangramViewController.h"
@implementation compactTangramViewController
@synthesize currentLevel;
//Initializer functions, setting up view hierarchy.
-(void) viewDidLoad
{
//Set up levelstepper.
levelStepper = 1;
//Set up "state" classes.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationHandler:) name:@"finishedCurrentLevel" object:nil];
//Attach level with clue 1/1.
currentLevel = [BGTangramLevel levelWithClue: [BGTangramClues clueFromPack:1 level:levelStepper] frame:self.view.frame];
[self.view addSubview:currentLevel];
[super viewDidLoad];
}
//Release objects.
-(void) dealloc
{
[currentLevel release];
[super dealloc];
}
//Notification handling.
-(void) notificationHandler: (NSNotification*) notification
{
//Execute kill current level.
if ([notification name] == @"finishedCurrentLevel") [self finishedCurrentLevel];
}
-(void) finishedCurrentLevel
{
//Remove - and release (dealloc) - previous clue.
[currentLevel removeFromSuperview];
[currentLevel release];
//Step level.
if (levelStepper == 1) levelStepper =2; else levelStepper = 1;
//Attach level with clue 1/2.
currentLevel = [BGTangramLevel levelWithClue: [BGTangramClues clueFromPack:1 level:levelStepper] frame:self.view.frame];
[self.view addSubview:currentLevel];
}
@end
BGTangramClues.h
#import <Foundation/Foundation.h>
#import "compactTangramGlobals.h"
//A "semi-abstract" class to have Point object.
@interface BGPoint : NSObject
{
float xCoord;
float yCoord;
}
@property float xCoord;
@property float yCoord;
//Returns an autorelease-instance of BGPoint class.
+(BGPoint*) pointWithX: (float) sentX andY: (float) sentY;
@end
//A clue object can be returned from the "clue-library".
@interface BGTangramClue : NSObject
{
NSArray *cluePolyVertices;
}
@property (nonatomic, assign) NSArray *cluePolyVertices;
//Returns an autorelease-instance of BGTangramClue class.
+(BGTangramClue*) clueWithPolyVertices: (NSArray*) sentPolyVertices;
@end
//The clue library.
@interface BGTangramClues : NSObject { }
+(BGTangramClue*) clueFromPack: (int) requestedPack level: (int) requestedLevel;
@end
BGTangramClues.m
#import "BGTangramClues.h"
@implementation BGPoint
@synthesize xCoord, yCoord;
+(BGPoint*) pointWithX: (float) sentX andY: (float) sentY
{
BGPoint *allocatedPoint = [[BGPoint alloc] init];
[allocatedPoint autorelease];
allocatedPoint.xCoord = sentX;
allocatedPoint.yCoord = sentY;
return allocatedPoint;
}
@end
@implementation BGTangramClue
@synthesize cluePolyVertices;
//Allocating.
+(BGTangramClue*) clueWithPolyVertices: (NSArray*) sentPolyVertices
{
BGTangramClue *allocatedClue = [[BGTangramClue alloc] init];
[allocatedClue autorelease];
allocatedClue.cluePolyVertices = sentPolyVertices;
return allocatedClue;
}
@end
@implementation BGTangramClues
+(BGTangramClue*) clueFromPack: (int) requestedPack level: (int) requestedLevel;
{
//Will receive an autorelease flag from the class method.
BGTangramClue *currentClue;
switch (requestedPack)
{
//--------------------
//-------------------- CluePack 1
//--------------------
case 1 :
switch (requestedLevel)
{
case 1 :
//-------------------- Clue 1. The logo "T".
currentClue = [BGTangramClue
clueWithPolyVertices: [NSArray arrayWithObjects:
//Poly 1.
[NSArray arrayWithObjects:
[BGPoint pointWithX: 40 andY: 150],
[BGPoint pointWithX: 280 andY: 150],
[BGPoint pointWithX: 280 andY: 210],
[BGPoint pointWithX: 220 andY: 210],
[BGPoint pointWithX: 220 andY: 330],
[BGPoint pointWithX: 100 andY: 330],
[BGPoint pointWithX: 100 andY: 210],
[BGPoint pointWithX: 40 andY: 210],
nil], //Poly 1 cap.
nil]];//Polygons cap.
//-------------------- End of clue
break;
case 2 :
//-------------------- Clue 2. Inverse Arrow.
currentClue = [BGTangramClue
clueWithPolyVertices: [NSArray arrayWithObjects:
//Poly 1.
[NSArray arrayWithObjects:
[BGPoint pointWithX: 70 andY: 150],
[BGPoint pointWithX: 250 andY: 150],
[BGPoint pointWithX: 250 andY: 320],
[BGPoint pointWithX: 165.148 andY: 235.148],
[BGPoint pointWithX: 190 andY: 210],
[BGPoint pointWithX: 130 andY: 210],
[BGPoint pointWithX: 130 andY: 270],
[BGPoint pointWithX: 154.852 andY: 245.148],
[BGPoint pointWithX: 240 andY: 330],
[BGPoint pointWithX: 70 andY: 330],
nil], //Poly 1 cap.
nil]];//Polygons cap.
//-------------------- End of clue
break;
} //CluePack cap.
//-------------------- End of CluePack 1
//--------------------
break;
} //Cleapacks cap.
//Send selected clue instance.
return currentClue;
}
@end
BGTangramLevel.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "BGTangramClues.h"
@interface BGTangramLevel : UIView {
//The screens graphic context.
CGContextRef screenContext;
//"Local" C-Style Clue.
int cluePolysAmount; //Max 7 of course.
int cluePolyVerticesAmount[7]; //Max 23 per clue poly.
CGPoint cluePolyVertices[7][23]; //The "worst" case is 5*3+2*4 = 23 vertex (maybe smaller).
//"Listener" flags.
BOOL puzzleCompleted;
}
//Initializers.
+(id)levelWithClue: (BGTangramClue*) clue frame: (CGRect) frame;
-(id)initWithClue: (BGTangramClue*) sentClue frame:(CGRect)frame;
//Test if the puzzle is completed.
-(void) isSolved;
@end
BGTAngramLevel.m
#import "BGTangramLevel.h"
#define CYCLE_CLUE_POLYS for (int cluePolyIndex = 0; cluePolyIndex <= cluePolysAmount-1; cluePolyIndex++)
@implementation BGTangramLevel
//Allocated instance.
+(id)levelWithClue: (BGTangramClue*) clue frame: (CGRect) frame
{
BGTangramLevel *allocatedLevel = [[BGTangramLevel alloc] initWithClue: clue frame:frame];
return allocatedLevel;
}
-(id)initWithClue: (BGTangramClue*) clue frame:(CGRect)frame
{
if (self=[self initWithFrame:frame])
{
//Copy the point data into the C-arrays.
//Count polygons.
cluePolysAmount = [clue.cluePolyVertices count];
//Count vertices.
for (int polyIndex = 0; polyIndex <= cluePolysAmount-1; polyIndex++)
cluePolyVerticesAmount[polyIndex] = [[clue.cluePolyVertices objectAtIndex:polyIndex] count];
//Import vertex data.
for (int polyIndex = 0; polyIndex <= cluePolysAmount-1; polyIndex++)
for (int vertexIndex = 0; vertexIndex <= cluePolyVerticesAmount[polyIndex]-1; vertexIndex++)
cluePolyVertices[polyIndex][vertexIndex] = CGPointMake([[[clue.cluePolyVertices objectAtIndex:polyIndex] objectAtIndex:vertexIndex] xCoord],
[[[clue.cluePolyVertices objectAtIndex:polyIndex] objectAtIndex:vertexIndex] yCoord]);
}
return self;
}
//The "render" method.
-(void) drawRect: (CGRect)rect
{
//Draw the puzzle polygon from the clue array.
screenContext = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(screenContext, 1.0, 0.0, 0.0, 1.0);
CGContextSetLineJoin(screenContext, kCGLineJoinRound);
CGContextSetLineWidth(screenContext, 0.5);
CYCLE_CLUE_POLYS
{
for (int vertexStepper = 0; vertexStepper <= cluePolyVerticesAmount[cluePolyIndex]-1; vertexStepper++)
{
CGContextMoveToPoint(screenContext, cluePolyVertices[cluePolyIndex][vertexStepper].x, cluePolyVertices[cluePolyIndex][vertexStepper].y);
CGContextAddLineToPoint(screenContext, cluePolyVertices[cluePolyIndex][((vertexStepper<cluePolyVerticesAmount[cluePolyIndex]-1)?vertexStepper+1:0)].x, cluePolyVertices[cluePolyIndex][((vertexStepper<cluePolyVerticesAmount[cluePolyIndex]-1)?vertexStepper+1:0)].y);
}
}
CGContextClosePath(screenContext);
CGContextStrokePath(screenContext);
}
//Finger released.
-(void) touchesEnded: (NSSet*)touches withEvent: (UIEvent*)event
{
//The completement condition is a simple released tap for now...
puzzleCompleted = YES;
//Test if puzzle is completed.
[self isSolved];
}
//Test if the puzzle is completed.
-(void) isSolved
{
if (puzzleCompleted) //Solved.
{
//"Notify viewController".
[[NSNotificationCenter defaultCenter] postNotificationName:@"finishedCurrentLevel" object:nil];
}
}
-(void) dealloc
{
NSLog(@"Level dealloc invoked");
[super dealloc];
}
@end
This is really kinda "skeleton". Anyway, as I expected, this shrinken version works now, but with the Object Allocation instrunment shows incrementing BGTangramLevel allocations.
Is it an "acceptable" way to organize my app? With this Clue-library stuff, and the others. maybe the UIImage-s, or ImageViews drives the fresh allocation crash in the extended/original app?
Nozzi, what do you suggest on redesigning?