Variables in a class - iphone

#interface characterclass : CCSprite
{
bool alive;
int speed;
int jumpamount = 10; <--- error
}
#property bool alive;
#property int speed;
#property int jumpamount;
#end
how do i do this like in my code, I want to have a variable in my class that equals 10.

You need to assign these values in the initializer of your class's instances. Create an instance method called - (id)init:
- (id)init{
self=[super init];
if (self) {
jumpamount=10;
}
return self;
}
Note that you no longer need to declare your ivars like that. #property will create an ivar for you.

Related

Making an Integer Array in Objective-C

I want to have an internal int array for my class, but I can't seem to get XCode to let me. The array size needs to be set on initialization so I can't put the size directly into the interface.
At the moment I've been trying:
#interface TestClass : NSObject {
int test[];
}
But it tells me that I'm not allowed. How to I refer to it in my interface, and then how do I allocate it when I create the implementation?
Sorry for a somewhat standard sounding question, but I can't seem to find the answer I need from searching.
edit: I want to use an array because it's apparently much faster than using an NSArray
You can use a number of methods to overcome this problem, but the easiest is to simply make the instance variable a pointer, like this:
#interface TestClass : NSObject {
int *test;
}
#property int *test;
#end
Synthesizing the property will give it getter and setter methods which you can use to set its contents:
#implementation TestClass
#synthesize test;
//contents of class
#end
You can then use it like this:
TestClass *pointerTest = [[TestClass alloc] init];
int *array = (int *)malloc(sizeof(int) * count);
//set values
[pointerTest setTest:array];
[pointerTest doSomething];
However, using objects like NSNumber in an NSArray is a better way to go, perhaps you could do something like this:
#interface TestClass : NSObject {
NSArray *objectArray;
}
#property (nonatomic, strong) NSArray *objectArray;
#end
#implementation TestClass
#synthesize objectArray;
//contents of class
#end
You can then set its contents with a pointer to an NSArray object:
NSArray *items = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:2], nil];
TestClass *arrayClass = [[TestClass alloc] init];
[arrayClass setItems:items];
[arrayClass doSomething];
When retaining objects upon setting them (like the previous example), always make sure you deallocate the object in the classes dealloc method.
A C array is just a sufficiently sized raw memory buffer. Foundation has a nice wrapper around raw memory that frees you from all the manual memory management: NSMutableData
The following approach gives you automatic memory management plus proper encapsulation.
#interface TestClass : NSObject
#property (nonatomic, readonly) int *testArray;
#property (nonatomic, readonly) NSUInteger testArraySize;
#end
#implementation TestClass
{
NSMutableData *_testData;
}
- (id)initWithSize:(NSUInteger)size
{
self = [self init];
if (self != nil) {
_testData = [NSMutableData dataWithLength:size];
}
}
- (int *)testArray
{
return [_testData mutableBytes];
}
- (NSUInteger)testArraySize
{
return [_testData length];
}
#end
As you see, the ivar does not have to be declared in the #interface.
Try something like this:
#interface TestClass : NSObject
{
int *_test;
}
#property (assign) int *test;
#end
#implementation TestClass
- (instancetype)init
{
if (self = [super init])
{
_test = malloc(sizeof(int) * 20);
}
return self;
}
- (int *)test
{
return _test;
}
- (void)setTest:(int*)test
{
memcpy(&_test, &test, sizeof(_test));
}
- (void)dealloc
{
free(_test);
}
#end

Pass values from a UIViewController to another

before the closing of my FlipsideViewController I have these values
shours
sminutes
sseconds
srecharge
change
from the declaration
int shours;
int sminutes;
int sseconds;
int srecharge;
bool change;
Now I want to pass these variables to another UIViewController (MainViewController) in these other variables
mhours
mminutes
mseconds
mrecharge
mchange
What's the simplest method to do this?
Create a custom object property on your MainViewController and set it on your FlipsideViewController or you can't do it for some reason: Create an object to hold these values and put it into NSUserDefaults and read on MainViewController.
I would simply create a "Model" class that holds those vars and pass the model class from one view controller to the next. Once it's linked in view1 & view2 during transition from view1 to view2, then it's automatically updated when transitioning back from view2 to view1. Use #property (assign) int shours so you have setters and getters created.
With this approach, using segues will work just fine. You don't need to use NSUserDefaults or NSNotificationCenter.
I would create a class to hold these values. Then pass this object between view controllers.
Something like this:
Interface file:
//
// MyObject.h
// SOObjectPassing
//
// Created by Wilson, LJ on 11/15/12.
// Copyright (c) 2012 Arkansas Children's Hospital. All rights reserved.
//
#import <Foundation/Foundation.h>
#interface MyObject : NSObject {
int shours;
int sminutes;
int sseconds;
int srecharge;
bool change;
}
#property (nonatomic, assign) int shours;
#property (nonatomic, assign) int sminutes;
#property (nonatomic, assign) int sseconds;
#property (nonatomic, assign) int srecharge;
#property (nonatomic, assign) BOOL change;
-(id) initWithHours:(int)hours
minutes:(int)minutes
seconds:(int)seconds
recharge:(int)recharge
changed:(BOOL)changed;
#end
Implementation file:
//
// MyObject.m
// SOObjectPassing
//
// Created by Wilson, LJ on 11/15/12.
// Copyright (c) 2012 Arkansas Children's Hospital. All rights reserved.
//
#import "MyObject.h"
#implementation MyObject
#synthesize shours = _shours;
#synthesize sminutes = _sminutes;
#synthesize sseconds = _sseconds;
#synthesize srecharge = _srecharge;
#synthesize change = _change;
-(id) initWithHours:(int)hours
minutes:(int)minutes
seconds:(int)seconds
recharge:(int)recharge
changed:(BOOL)changed {
if ((self = [super init])) {
_shours = hours;
_sminutes = minutes;
_sseconds = seconds;
_srecharge = recharge;
_change = changed;
}
return self;
}
#end
And instantiate your object like this:
MyObject *myObject = [[MyObject alloc] initWithHours:2
minutes:3
seconds:4
recharge:1
changed:NO];
Then just pass that entire object to your other VC (s).
Here is a sample project illustrating this.

Getter for a block on a class?

I am creating a property on a class that is gonna be a block.
It is being defined like
#property (nonatomic, strong) void (^ myBlock)();
I would like to do lazy creation of that property, so I want to create a getter for that block to run when the the property is used by some code.
If the property was not a block and was a NSArray for example, I would do the setter like this:
#synthesize myProperty = _myProperty;
- (NSArray *)myProperty {
if (_myProperty) {
_myProperty = [[NSArray alloc] init];
}
return _myProperty;
}
How do I do a getter (lazy instantiation) for a property that is a block?
NOTE: this block is inside a singleton.
thanks
#property (nonatomic, copy) void (^ myBlock)();
- (void (^)())myBlock {
if (!_myBlock) {
self.myBlock = ^ () {
NSLog(#"Do something");
};
}
return _myBlock;
}
in h
typedef BOOL (^MyProcessorBlock)(id param1);
#property (nonatomic, copy) MyProcessorBlock myBlockProperty
in m (if you use old objc pre 2.0, pre summer 2012)
#synthesize myBlockProperty = _myBlockProperty;
in any case in m file
- (MyBlock)myBlockProperty {
if(!_myBlockProperty) {
_myBlockProperty = ^(self) { ..... };
}
return _myBlockProperty;
}

Accessing property of returned object causes EXC_BAD_ACCESS

I have a class defined where the top two properties are accessible without issue. Only the UIColor* is a problem. I imagine something isn't being alloc'd, init'd, retained, or released properly and have been changing various things without success. Any help would be grand.
// PieceScore.h
#interface PieceScore : NSObject {
int pieceCount;
BOOL greatMatch;
UIColor *colorMatched;
}
#property (nonatomic) int pieceCount;
#property (nonatomic) BOOL greatMatch;
#property (nonatomic, retain) UIColor *colorMatched;
-(id) initWithPieceCount:(int)pC withGreatMatch:(BOOL)gM withColorMatched:(UIColor*)cM;
#end
// PieceScore.m
#implementation PieceScore
#synthesize pieceCount, greatMatch, colorMatched;
-(id) init {
return [self initWithPieceCount:0 withGreatMatch:NO withColorMatched:[UIColor clearColor]];
}
-(id) initWithPieceCount:(int)pC withGreatMatch:(BOOL)gM withColorMatched:(UIColor*)cM {
self = [super init];
if (self) {
pieceCount = pC;
greatMatch = gM;
colorMatched = cM;
}
return self;
}
#end
It is initialized and returned by another class as follows:
PieceScore* pieceScore = [[[PieceScore alloc] initWithPieceCount:piecesRemoved withGreatMatch:greatMatch withColorMatched:pieceColor] autorelease];
return pieceScore;
NOTE: (pieceColor is a UIColor*)
Then, the UIColor* is used in a method of yet another class:
- (void) labelRender:(UILabel*)label withColor:(UIColor *)color {
// ...
label.textColor = color; // Thread 1: Program received signal: "EXC_BAD_ACCESS".
// ...
}
In the debug view, I can see that color is actually being passed as a UIColor*, but is error-ing out when being assigned to the label's textColor property.
You are setting the ivar to an autoreleased variable. Make sure you use the property so that it is properly retained.
Change colorMatched = cM; to self.colorMatched = cM;
The ivars in your initWithPieceCount:piecesRemoved:withGreatMatch:withColorMatched need to make sure they retain any values which may be provided as autoreleased. You shouldn't use properties within your init methods,
See here for some discussion
so do a retain on the passed object.
i.e. colormatched = [cM retain];

Setter method not being called

I have this code:
.h
int cellsPerRow;
#property int cellsPerRow;
.m
#synthesize cellsPerRow;
-(void)init {
...
cellsPerRow = 4;
}
-(void)setCellsPerRow:(int)cellsPerRowLocal {
cellsPerRow = cellsPerRowLocal;
....
}
But the setter method isn't being called. Any ideas why?
You are assigning to the variable instead of the property. Instead of:
cellsPerRow = 4;
You need to do either:
self.cellsPerRow = 4;
or
[self setCellsPerRow:4];
The former is transformed by the compiler into the later, so they are equivalent.
The property and synthesize create the setter and getter methods for you. In essence what you are doing is actually override the methods that were created for you in the first place.
Don't do that. Just use dot notation, like so, self.cellsPerRow = cellsPerRowLocal. This will set your cellsPerRow ivar to whatever you want it to be in cellsPerRowLocal.
In you header file:
int cellsPerRow;
#property (nonatomic, retain) int cellsPerRow;
In your implementation file:
#synthesize cellsPerRow;
- (void) inThisMethodYouSetcellsPerRow {
cellsPerRowLocal = ... ;
self.cellsPerRow = cellsPerRowLocal;
}