EXC_BAD_ACCESS on NSMutableArray insertion - iphone

I am using an NSMutableArray defined in a CCLayer subclass as follows:
//
// GameOverScene.h
// Cocos2DSimpleGame
//
// Created by Ray Wenderlich on 2/10/10.
// Copyright 2010 Ray Wenderlich. All rights reserved.
//
#import "cocos2d.h"
#interface scoLayer : CCColorLayer {
CCLabelTTF *_label;
CCLabelTTF *_howtoplay;
NSMutableArray *highscores;
}
#property (nonatomic, retain) CCLabelTTF *label;
#property (nonatomic, retain) NSMutableArray *highscores;
#property (nonatomic, retain) CCLabelTTF *back;
+ (id)initWithScore:(int)lastScore;
+(void)print_label:(int)lb;
+(void)menu;
#end
#interface sco : CCScene {
scoLayer *_layer;
}
#property (nonatomic, retain) scoLayer *layer;
#end
Here is the .m file for the class:
#implementation sco
#synthesize layer = _layer;
- (id)init {
if ((self = [super init])) {
self.layer = [scoLayer node];
[self addChild:_layer];
}
return self;
}
- (void)dealloc {
[_layer release];
_layer = nil;
[super dealloc];
}
#end
#implementation scoLayer
#synthesize label = _label;
#synthesize highscores ;
//#synthesize how_to_play ;
#synthesize back;
-(id) init
{
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
self.label = [CCLabelTTF labelWithString:#"" fontName:#"Arial" fontSize:16];
//self.how_to_play = [CCLabelTTF labelWithString:#"" fontName:#"Arial" fontSize:32];
self.highscores = [[NSMutableArray alloc] initWithObjects:nil ];
// [highscores addObject:#"asdf"];
// NSLog(#"hig %#", [highscores objectAtIndex:0]);
_label.color = ccc3(0,0,0);
_label.position = ccp(winSize.width/2, winSize.height/2);
[self addChild:_label z:100];
[self runAction:[CCSequence actions:
[CCDelayTime actionWithDuration:3],
[CCCallFunc actionWithTarget:self selector:#selector(gameOverDone)],
nil]];
CCSprite *bk1 =[CCSprite spriteWithFile:#"bg3.png" ];//rect: CGRectMake(0, 0, 40, 480)];
[bk1 setPosition:ccp(160, 239)];
[self addChild:bk1 z:0];
CCMenuItem *back = [CCMenuItemImage
itemFromNormalImage:#"gameBackButton.png" selectedImage:#"gameBackButton.png"
target:self selector:#selector(back_game:)];
CCMenu *menu1 = [CCMenu menuWithItems:back,nil];
menu1.position = ccp(70, 100);
[menu1 alignItemsVerticallyWithPadding: 40.0f];
// [self addChild:menu z: 2];
[self addChild:menu1 z: 0];
}
return self;
}
In this function:
+(id)initWithScore:(int)lastScore
{
NSLog(#"score %d", lastScore);
//NSMutableArray *highscores = [[NSMutableArray alloc] initWithObjects:nil ];
//[highscores addObject:#"asdf"];
if([highscores count] == 0)
}
I want to use the highscores array and insert the data (lastScore), but when I do this the application exits with an EXC_BAD_ACCESS signal. How can I fix this error?

The + before the method declaration indicates, that this is a class method. So you have no access to instance variables.
I think this is more what you want:
-(id)initWithScore:(int)lastScore
{
NSLog(#"score %d", lastScore);
if(!self = [super init])
return nil;
highscores = [[NSMutableArray alloc] init];
[highscores addObject:lastScore];
return self;
}

You're on the right track, but unless you have many different highscore tables you don't need to make it a separate class, as you've tried to do now. (I.e. 'create many highscore table instances with a class'.) You can of course use a class and create an object of class highscoretable at [[alloc] init] (as yan kun shows), but if all you need is a mutable array to add highscores to in your game, just allocate one in the app delegate, or use other methods for variables shared between viewcontrollers, I think.

Related

Change UIView's background color

I am doing some exercises with delegate, but now I have a problem with a UIView. This is my storyboard
I want to change the color of the UIView with 3 UISliders. The range of UISliders is from 0 to 255.
And this is my code:
ColorField is the UIView custom class
ColorField.h
#import <UIKit/UIKit.h>
#protocol ColorFieldDelegate <NSObject>
-(NSArray *)giveMeColors;
#end
#interface ColorField : UIView
#property (nonatomic , weak) IBOutlet id<ColorFieldDelegate> delegate;
#end
ColorField.m
#import "ColorField.h"
#implementation ColorField
#synthesize delegate = _delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
NSArray *arrayOfColors = [self.delegate giveMeColors];
int red = [[arrayOfColors objectAtIndex:0] intValue];
int green = [[arrayOfColors objectAtIndex:1] intValue];
int blue = [[arrayOfColors objectAtIndex:2] intValue];
NSLog(#"Red --> %d" ,red);
NSLog(#"Green --> %d" ,green);
NSLog(#"Blue --> %d \n\n" ,blue);
self.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}
#end
ColorViewController.h
#import <UIKit/UIKit.h>
#import "ColorField.h"
#interface ColorViewController : UIViewController <ColorFieldDelegate>
#property (nonatomic) IBOutlet ColorField *colorField;
#property (weak, nonatomic) IBOutlet UISlider *redSlider;
#property (weak, nonatomic) IBOutlet UISlider *greenSlider;
#property (weak, nonatomic) IBOutlet UISlider *blueSlider;
#end
ColorViewController.m
#import "ColorViewController.h"
#interface ColorViewController ()
#property (nonatomic) double redQuantity;
#property (nonatomic) double greenQuantity;
#property (nonatomic) double blueQuantity;
#end
#implementation ColorViewController
#synthesize colorField = _colorField;
#synthesize redSlider;
#synthesize greenSlider;
#synthesize blueSlider;
#synthesize redQuantity;
#synthesize blueQuantity;
#synthesize greenQuantity;
- (void)viewDidLoad
{
[super viewDidLoad];
[self.colorField setDelegate:self];
[self.colorField setNeedsDisplay];
self.redQuantity = 125.0;
self.blueQuantity = 125.0;
self.greenQuantity = 125.0;
[self.colorField setNeedsDisplay];
// Do any additional setup after loading the view, typically from a nib.
}
-(ColorField *)colorField
{
if (_colorField == nil) {
_colorField = [[ColorField alloc] init];
}
return _colorField;
}
- (void)viewDidUnload
{
[self setColorField:nil];
[self setRedSlider:nil];
[self setGreenSlider:nil];
[self setBlueSlider:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
-(IBAction)changeRedQuantity:(UISlider *)sender
{
//methods of UISliders
self.redQuantity = [sender value];
[self.colorField setNeedsDisplay];
}
-(IBAction)changeBlueQuantity:(UISlider *)sender
{
self.blueQuantity = [sender value];
[self.colorField setNeedsDisplay];
}
-(IBAction)changeGreenQuantity:(UISlider *)sender
{
self.greenQuantity = [sender value];
[self.colorField setNeedsDisplay];
}
-(NSArray *)giveMeColors
{
NSNumber *redNumber = [NSNumber numberWithDouble:self.redQuantity];
NSNumber *greenNumber = [NSNumber numberWithDouble:self.greenQuantity];
NSNumber *blueNumber = [NSNumber numberWithDouble:self.blueQuantity];
NSArray *array = [[NSArray alloc] initWithObjects:redNumber, greenNumber,blueNumber, nil];
return array;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
BUT...this is the result: It show me only RED, GREEN and BLUE colors without gradation, for example: RGB (255,0,75) is THIS
and not THIS:
I don't know with it can't show me gradation...
Thanks!!
Marco Manzoni
You have to divide your slidervalues by 255.0.
[UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1.0];
colorWithRed only accepts values 0.0-1.0

iPhone app crash when call self.addChild in CCSprite subclass ..?

I have downloaded the ABC open source And turning source code into cocos2d 1.01.
Now I'm having problems with the init Sprite Subclass. ( my subclass is #interface OrbSprite : CCSprite )
This Code is endless loop and older cocos2d version.
-(id) init {
self = [super init];
if (self)
{
[self initWithFile:#"bubble1.png"];
Animation *bub = [Animation animationWithName:#"bubble" delay:0 images:#"bubble1.png", #"bubble2.png", nil];
self.bubble = bub;
[bub release];
[self addAnimation:bubble];
Label *l = [[Label alloc] initWithString:#"" dimensions:CGSizeMake(45, 45) alignment:UITextAlignmentCenter
fontName:#"Arial Rounded MT Bold" fontSize:18];
self.label = l;
[l release];
}
return self; }
I search of a solution And can be solved by changing the name of init Method.
-(id) initWithBubbleImage {
if ((self = [super initWithFile :#"bubble1.png"]))
{
NSLog(#"OrbSprite init in if self Method");
bubblea = [NSArray arrayWithObjects:#"bubble1.png",#"bubble2.png",nil];
bub = [CCAnimation animationWithFrames:bubblea delay:0 ];
[[CCAnimationCache sharedAnimationCache] addAnimation:bub name:#"bubbleAnim"];
self.bubble = bub;
[bub release];
label = [[CCLabelTTF alloc] initWithString:#"" dimensions:CGSizeMake(45, 45) alignment:UITextAlignmentCenter
fontName:#"Arial Rounded MT Bold" fontSize:18];
}
return self; }
???? The problem is that when change init name already, I found in " -(void) setLabelStr:(NSString ) str " in the same subclass was error to addChild: in Debug area..
" ** Assertion failure in -[OrbSprite addChild:] " and " Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil' "
This is method in same subclass
- (void) setLabelStr:(NSString *) str {
[label setString:str];
[self addChild:label];
[label setAnchorPoint:ccp(0, 13)]; }
Anybody help me please.......
Thank you very much.
=====================================================================
E D I T -- E D I T -- E D I T -- E D I T -- E D I T -- E D I T
I've done this as a reply.
but still don't work
Hear's is .h and .m code
OrbSprite.h
this is code
#import "cocos2d.h"
#interface OrbSprite : CCSprite
{
CCLabelTTF *label;
CCAnimation *bubble;
BOOL isBubble;
BOOL isHidden;
int order;
CCSequence *popSequence;
}
#property (nonatomic, retain) CCLabelTTF *label;
#property (nonatomic, retain) CCSequence *popSequence;
#property (nonatomic, retain) CCAnimation *bubble;
#property (nonatomic, retain) NSArray *bubblea;
#property (readwrite) BOOL isBubble;
#property (readwrite) BOOL isHidden;
#property (readwrite) int order;
-(id)initWithBubbleImage;
- (void) pop;
- (void) setLabelStr:(NSString *) str;
- (void) showBubble;
- (void) reset;
#end
OrbSprite.m
this is code
#import "OrbSprite.h"
#implementation OrbSprite
#synthesize bubble;
#synthesize label;
#synthesize isBubble;
#synthesize isHidden;
#synthesize popSequence;
#synthesize order;
#synthesize bubblea;
-(id) initWithBubbleImage {
if ((self = [super initWithFile:#"bubble1.png"]))
{
bubblea = [NSArray arrayWithObjects:#"bubble1.png",#"bubble2.png",nil];
bubble= [CCAnimation animationWithFrames:bubblea delay:0 ];
[[CCAnimationCache sharedAnimationCache] addAnimation:bub name:#"bubbleAnim"];
label = [[CCLabelTTF alloc] initWithString:#"" dimensions:CGSizeMake(45, 45)
alignment:UITextAlignmentCenter fontName:#"Arial Rounded MT Bold" fontSize:18];
}
return self;
}
- (void) pop {
isBubble = NO;
popSequence = [CCSequence actions:[CCScaleTo actionWithDuration:.1 scale:.5],
[CCScaleTo actionWithDuration:.1 scale:2], [CCCallFunc actionWithTarget:self
selector:#selector(finishedPopSequence)], nil];
[self runAction:popSequence];
}
- (void) finishedPopSequence {
self.scale = 1;
[self setDisplayFrameWithAnimationName:#"bubble" index:0]; }
- (void) reset {
self.scale = 1;
[self setDisplayFrameWithAnimationName:#"bubble" index:0]; }
- (void)showBubble {
isBubble = YES;
[self removeChild:label cleanup:NO];
[self setDisplayFrameWithAnimationName:#"bubbleAnim" index:1];
self.scale = .5;
id Orbshowscale = [CCScaleTo actionWithDuration:1 scale:1.5];
id Orbshowscale2= [CCScaleTo actionWithDuration:.1 scale:1];
[self runAction:[CCSequence actions:Orbshowscale,Orbshowscale2 , nil]]; }
- (void) setLabelStr:(NSString *) str {
[label setString:str];
[self addChild:label]; //<<< *** Assertion failure in -[OrbSprite addChild:]
[label setAnchorPoint:ccp(0, 13)]; }
#end
I already fix over-release problem..
but it still dont' work ..
Also found the same problem is
***Assertion failure in -[OrbSprite addChild:]
***Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil'
Thanks to everyone who has kindly ...
Looks as if you're over-releasing the variable "bub" in your init method. You don't create it via an alloc or create method call, so you shouldn't be releasing it.
Use Alloc and after that release it.
You've assigned bub to self.bubble and then you release bub. Both point to the same address. The same is happening for self.label. Try it this way:
-(id) init {
self = [super init];
if (self)
{
[self initWithFile:#"bubble1.png"];
Animation *bub = [Animation animationWithName:#"bubble" delay:0 images:#"bubble1.png", #"bubble2.png", nil];
self.bubble = bub;
//[bub release]; <-- This shouldn't be done
[self addAnimation:bubble];
Label *l = [[Label alloc] initWithString:#"" dimensions:CGSizeMake(45, 45) alignment:UITextAlignmentCenter
fontName:#"Arial Rounded MT Bold" fontSize:18];
self.label = l;
//[l release]; <-- This shouldn't be done
}
return self; }
EDIT- Try this-
[self addChild:self.label]; //<<< *** Assertion failure in -[OrbSprite addChild:]

Why is my loaded nib crashing when memory is released?

If I run Build and Analyze this loads without errors according to the Analyzer but the app crashes. If I remove the [myStates release]; analyzer complains about possible leak but the nib loads and runs just fine. MyStateList is a nib which has a pickerview inside that loads a plist if this helps. Please help.
Main TrialViewControllerViewController Implementation File
#import "TrialViewControllerViewController.h"
#import "MyStateList.h"
#implementation TrialViewControllerViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyStateList *myStates = [[MyStateList alloc] initWithNibName:#"MyStateList" bundle:nil];
[self.view addSubview:[myStates view]];
//[myStates release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end
Here is what i am trying to load
MyStateList.h
#import <UIKit/UIKit.h>
#interface MyStateList : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
UIPickerView *pickerView;
NSMutableArray *statesArray; // Written array
NSDictionary *stateListDictionary,*stateListDictionaries;
NSArray *firstDisplayArray,*updateDisplayArray,*switchDisplayArray;
NSInteger dTag;
NSString *nott,*verify,*notes;
IBOutlet UILabel *labelOne,*labelTwo,*labelThree,*labelName;
}
#property (nonatomic, retain) UIPickerView *pickerView;
#property (nonatomic, retain) NSDictionary *stateListDictionary,*stateListDictionaries;
#property (nonatomic, retain) NSArray *firstDisplayArray,*updateDisplayArray,*switchDisplayArray;
#property (nonatomic, retain) IBOutlet UILabel *labelOne,*labelTwo,*labelThree,*labelName;
#property (nonatomic, retain) NSString *nott,*verify,*notes;
- (void)loadData;
- (void)placeData;
- (void)createPicker;
#end
MyStateList.m
#import "MyStateList.h"
#implementation MyStateList
#synthesize pickerView;
#synthesize stateListDictionary,stateListDictionaries,firstDisplayArray,updateDisplayArray,switchDisplayArray ;
#synthesize labelOne,labelTwo,labelThree,labelName;
#synthesize nott,verify,notes;
- (void)viewDidLoad
{
[super viewDidLoad];
[self createPicker];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [statesArray count];
}
-(UIView *)pickerView:(UIPickerView *)pickerViewCust viewForRow:(NSInteger)row forComponent: (NSInteger)component reusingView:(UIView *)view
{
NSString *rowItem = [statesArray objectAtIndex: row];
UILabel *lblRow = [[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerViewCust bounds].size.width, 44.0f)]autorelease];
[lblRow setTextAlignment:UITextAlignmentCenter];
[lblRow setTextColor: [UIColor blueColor]];
[lblRow setText:rowItem];
[lblRow setBackgroundColor:[UIColor clearColor]];
return lblRow;
}
- (void)createPicker
{
NSString *path = [[NSBundle mainBundle] pathForResource:
#"StateArray" ofType:#"plist"];
stateListDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
labelName.text = [NSString stringWithFormat:#"Arizona"];
[self loadData];
float screenWidth = [UIScreen mainScreen].bounds.size.width;
float pickerWidth = screenWidth * 1 / 2;
float xPoint = screenWidth / 2 - pickerWidth / 1;
pickerView = [[UIPickerView alloc] init];
[pickerView setDataSource: self];
[pickerView setDelegate: self];
[pickerView setFrame: CGRectMake(xPoint, 280.0f, pickerWidth, 180.0f)];
pickerView.showsSelectionIndicator = YES;
[pickerView selectRow:2 inComponent:0 animated:YES];
[self.view addSubview: pickerView];
}
- (void)loadData
{
firstDisplayArray = [stateListDictionary objectForKey:#"Arizona"];
dTag = 1;
[self placeData];
stateListDictionary = nil; // kill the list
statesArray = [[NSMutableArray alloc] init];
[statesArray addObject:#"Alabama"];
[statesArray addObject:#"Alaska"];
[statesArray addObject:#"Arizona"];
[statesArray addObject:#"Arkansas"];
[statesArray addObject:#"California"];
}
- (void)placeData
{
if (dTag == 1)
{
switchDisplayArray = firstDisplayArray;
dTag = 0;
} else {
switchDisplayArray = updateDisplayArray;
}
nott = [switchDisplayArray objectAtIndex:0];
verify = [switchDisplayArray objectAtIndex:1];
notes = [switchDisplayArray objectAtIndex:2];
labelOne.text = nott;
labelTwo.text = verify;
labelThree.text = notes;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
NSString *path = [[NSBundle mainBundle] pathForResource:
#"StateArray" ofType:#"plist"];
stateListDictionaries = [NSDictionary dictionaryWithContentsOfFile:path];
labelName.text = [statesArray objectAtIndex: row];
updateDisplayArray = [stateListDictionaries objectForKey:labelName.text];
[self placeData];
}
- (void)dealloc
{
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
[super dealloc];
}
#end
If I had to guess, MyStatesList is a subclass of UIViewController.
If you release myStates at the end of the block, you're essentially removing the brain from your view controller, but leaving its body there. You need to keep the controller itself around as well as the view, as the view is owned by the controller. Not the other way around.
The view from your view controller is retained by the view, but you killed the view controller itself. The bigger problem is you CAN'T just add views from UIViewControllers in this manner. On iOS5 you have the ability to use addChildViewController: and prior to that you can use one of the provided container controllers.
You do indeed need to release your MyStateList object.
Here's what's happening:
You initialize a new MyStateList, which has a retain count of 1
You add a subview to your view, and that subview is NOT the MyStateList object, but the ivar view of your MyStateList object.
When you don't release your myStates object, you are indeed leaking this object, since nothing has a reference to this object anymore, and the memory was never deallocated. (Its retain count never reached 0.)
That having been said, what kind of error occurs when your application crashes? I'm guessing that MyStateList is a UIViewController, and the view is then attempting to access/communicate with its parent, which has been released/deallocated.
In your -(void)dealloc; you are calling [super dealloc] first, this is wrong. Make it the last call in the method. This should fix your crash.
- (void)dealloc
{
// Wrong Way
[super dealloc];
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
}
`
- (void)dealloc
{
// Right way
[pickerView release];
[stateListDictionary release];
[stateListDictionaries release];
[statesArray release];
[super dealloc];
}
you add the view [myStates view], to the controller's view, so the view is hold by the controller's view.
then you release "myStates" for avoid memeory leak, it is removed.
and I guess in your view [myStates view], there must be some delegates related to the object "myState", but it was removed just before. So, the app crash.
To avoid both problems, memory leak and crash. I think you should make the "myStates" hold by your controller as a member variable. And you could release "myState" when your viewUnloaded.

"Program received signal "SIGABRT" when building a calculator

(I'm beginner.)
I'm practicing Navigation Controller. I try to implement a simple calculator.
I ran the code in simulator. After I pressed any button which was linked to "addFunction", "substractFunction", "multiplyFunction" or "divideFunction", It crashed.
The debugger marked the following code in main.m
int retVal = UIApplicationMain(argc, argv, nil, nil);
and said "Thread 1: Program received signal: "SIGABRT"."
Does anyone know how to cope with this situation? Thanks.
Here's the code:
ChangeAppView.h:
#import <UIKit/UIKit.h>
#class ChangeViewController;
#interface ChangeAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) UINavigationController *navigationController;
#end
ChangeAppDelegate.m:
#import "ChangeAppDelegate.h"
#import "ChangeViewController.h"
#implementation ChangeAppDelegate
#synthesize window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
navigationController = [[UINavigationController alloc] init];
self.window.rootViewController = navigationController;
ChangeViewController *changeViewController = [[ChangeViewController alloc] initWithNibName:#"ChangeViewController" bundle:nil];
[navigationController pushViewController:changeViewController animated:YES];
[changeViewController release];
[self.window makeKeyAndVisible];
return YES;
}
…
- (void)dealloc
{
[navigationController release];
[window release];
[super dealloc];
}
#end
CalculatorViewController.h:
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
{
IBOutlet UITextField *numberField1;
IBOutlet UITextField *numberField2;
IBOutlet UILabel *resultLabel;
}
#property (nonatomic , retain) IBOutlet UITextField *numberField1;
#property (nonatomic , retain) IBOutlet UITextField *numberField2;
#property (nonatomic , retain) IBOutlet UILabel *resultLabel;
-(IBAction)addFunction:(id)sender;
-(IBAction)substractFunction:(id)sender;
-(IBAction)multiplyFunction:(id)sender;
-(IBAction)divideFunction:(id)sender;
-(IBAction)clear:(id)sender;
-(IBAction)backgroundTap:(id)sender;
#end
CalculatorViewController.m:
#import "CalculatorViewController.h"
#implementation CalculatorViewController
#synthesize numberField1;
#synthesize numberField2;
#synthesize resultLabel;
-(IBAction)addFunction:(id)sender
{
float a = ([numberField1.text floatValue]);
float b = ([numberField2.text floatValue]);
resultLabel.text = [NSString stringWithFormat:#"%2.f" , a+b];
}
-(IBAction)substractFunction:(id)sender
{
float a = ([numberField1.text floatValue]);
float b = ([numberField2.text floatValue]);
NSString *result = [[NSString alloc] initWithFormat:#"%2.f" , a-b];
resultLabel.text = result;
[result release];
}
-(IBAction)multiplyFunction:(id)sender
{
float a = ([numberField1.text floatValue]);
float b = ([numberField2.text floatValue]);
resultLabel.text = [[NSString alloc] initWithFormat:#"%2.f" , a*b];
}
-(IBAction)divideFunction:(id)sender
{
float a = ([numberField1.text floatValue]);
float b = ([numberField2.text floatValue]);
resultLabel.text = [[NSString alloc] initWithFormat:#"%2.3f" , a/b];
}
-(IBAction)clear:(id)sender
{
numberField1.text = #"";
numberField2.text = #"";
resultLabel.text = #"";
}
-(IBAction)backgroundTap:(id)sender
{
[numberField1 resignFirstResponder];
[numberField2 resignFirstResponder];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[numberField1 release];
[numberField2 release];
[resultLabel release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
self.title = #"Calculator";
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
From the exception above, it seems that your IBActions are not properly connected.
As dasdom mentioned, delete all your buttons, create new buttons and then add IBAction methods accordingly.
Also one more thing i recognized in your code, in the multiply and divide methods there is a memory leak.You have written
resultLabel.text = [[NSString alloc] initWithFormat:#"%2.f" , a*b];
it should be
resultLabel.text = [[[NSString alloc] initWithFormat:#"%2.f" , a*b]autorelease];
or
resultLabel.text = [NSString StringWithFormat:#"%2.f" , a*b];
and do a similar change in divide method also.
To what did you link your backgroundtap method?
It seems that you buttons aren't buttons. They seem to be view. Delete the buttons from you nib and put new buttons there and link them you our IBActions.

Problems Adding MKPolygon as an Overlay to an MKMapView

Ey there, so as the title says, I am having a tough time adding an MKPolygon as an overlay to an MKMapView. Here is the relevant code:
ParkingMapViewContoller.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ParkingMapViewController : UIViewController <MKMapViewDelegate> {
MKMapView *mapView;
}
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
-(void)loadAnnotations;
-(void)showCurrentLocationButtonTapped:(id)sender;
#end
ParkingMapViewController.m
//...
#import "ParkingRegionOverlay.h"
//...
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#",self.title);
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:100 target:self action:#selector(showCurrentLocationButtonTapped:)];
/*MKMapPoint points[3] = {{38.53607,-121.765793}, {38.537606,-121.768379}, {38.53487,-121.770578}};
MKPolygon *polygon = [MKPolygon polygonWithPoints:points count:3];*/
ParkingRegionOverlay *polygon = [[ParkingRegionOverlay alloc] initialize];
[mapView addOverlay:polygon];
[self loadAnnotations];
CLLocationCoordinate2D centerCoord = { UCD_LATITUDE, UCD_LONGITUDE };
[mapView setCenterCoordinate:centerCoord zoomLevel:13 animated:NO]; //from "MKMapView+ZoomLevel.h"
}
//...
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
NSLog(#"in viewForOverlay!");
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonView* aView = [[[MKPolygonView alloc] initWithPolygon:(MKPolygon*)overlay] autorelease];
aView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
aView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
aView.lineWidth = 3;
return aView;
}
return nil;
}
//...
ParkingRegionOverlay.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface ParkingRegionOverlay : NSObject <MKOverlay> {
//CLLocationCoordinate2D origin;
MKPolygon *polygon;
//MKMapRect rect;
}
//#property (nonatomic) CLLocationCoordinate2D origin;
#property (nonatomic, retain) MKPolygon *polygon;
//#property (nonatomic) MKMapRect rect;
-(ParkingRegionOverlay*)initialize;
-(MKMapRect)boundingMapRect;
-(CLLocationCoordinate2D)coordinate;
#end
ParkingRegionOverlay.m
#import "ParkingRegionOverlay.h"
#implementation ParkingRegionOverlay
//#synthesize origin;
#synthesize polygon;
//#synthesize rect;
-(ParkingRegionOverlay*) initialize {
MKMapPoint points[3] = {{38.53607,-121.765793}, {38.537606,-121.768379}, {38.53487,-121.770578}};
polygon = [MKPolygon polygonWithPoints:points count:3];
polygon.title = #"Some Polygon";
return self;
}
- (MKMapRect)boundingMapRect{
MKMapRect bounds = MKMapRectMake(-121.770578,38.537606,-121.770578-(-121.765793),38.537606-38.53487);
return bounds;
}
- (CLLocationCoordinate2D)coordinate{
return CLLocationCoordinate2DMake((38.537606-38.53487)/2, (-121.770578-(-121.765793))/2);
}
#end
You see that NSLog I stuck in the viewForOverlay: method? Well that never shows up in the console, so that function is never called. Any idea of what's wrong? Many thanks!
The main issue is that the code is giving the map view latitude/longitude coordinates where it expects MKMapPoints. For an explanation of the difference, see "Understanding Map Geometry" in the Location Awareness Programming Guide. Use the MKMapPointForCoordinate function to convert from lat/long coordinates to an MKMapPoint.
The second issue is that in viewForOverlay, it is checking if overlay is of type MKPolygon. Your overlay class ParkingRegionOverlay contains an MKPolygon object inside it but is not itself of type MKPolygon.
To fix the main issue, you need to change the initialize and boundingMapRect methods:
-(id)init {
if (self = [super init]) {
MKMapPoint points[3];
CLLocationCoordinate2D c1 = {38.53607,-121.765793};
points[0] = MKMapPointForCoordinate(c1);
CLLocationCoordinate2D c2 = {38.537606,-121.768379};
points[1] = MKMapPointForCoordinate(c2);
CLLocationCoordinate2D c3 = {38.53487,-121.770578};
points[2] = MKMapPointForCoordinate(c3);
polygon = [MKPolygon polygonWithPoints:points count:3];
polygon.title = #"Some Polygon";
}
return self;
}
- (MKMapRect)boundingMapRect{
CLLocationCoordinate2D corner1 =
CLLocationCoordinate2DMake(38.537606, -121.770578);
MKMapPoint mp1 = MKMapPointForCoordinate(corner1);
CLLocationCoordinate2D corner2 =
CLLocationCoordinate2DMake(38.53487, -121.765793);
MKMapPoint mp2 = MKMapPointForCoordinate(corner2);
MKMapRect bounds =
MKMapRectMake(mp1.x, mp1.y, (mp2.x-mp1.x), (mp2.y-mp1.y));
return bounds;
}
Please notice by the way that I changed the method "initialize" to "init". Though it wasn't preventing the polygon from showing, the way you are overriding the initialization of ParkingRegionOverlay using a method called "initialize" and not calling [super init] does not follow convention. (Also remove "initialize" from the .h file.)
To fix the second issue, the viewForOverlay method should look like this:
- (MKOverlayView *)mapView:(MKMapView *)mapView
viewForOverlay:(id <MKOverlay>)overlay
{
NSLog(#"in viewForOverlay!");
if ([overlay isKindOfClass:[ParkingRegionOverlay class]])
//^^^^^^^^^^^^^^^^^^^^
{
//get the MKPolygon inside the ParkingRegionOverlay...
MKPolygon *proPolygon = ((ParkingRegionOverlay*)overlay).polygon;
MKPolygonView *aView = [[[MKPolygonView alloc]
initWithPolygon:proPolygon] autorelease];
//^^^^^^^^^^
aView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
aView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
aView.lineWidth = 3;
return aView;
}
return nil;
}
Finally, change the code in viewDidLoad:
ParkingRegionOverlay *polygon = [[ParkingRegionOverlay alloc] init];
[mapView addOverlay:polygon];
[polygon release]; //don't forget this
it seems to me that you forget to set your delegate
somthing like that
_mapView.delegate = self;
Have you set this?:
yourMap.delegate=self;
And what's your target? 3.x or 4.x?? I think MKPolygon is available from 4.0.
You can try to add the import clause to your prefix file like:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#endif