When executing
[self.blockViews addObject:curBlockView];
I get an error
2011-07-01 13:35:26.240 Block Breaker[42061:207] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x4e037a0
I am pretty new to Objective-C. Is it something in my init method?
//
// GameEngine.h
// Block Breaker
//
// Created by Chris Muench on 7/1/11.
// Copyright 2011 N/A. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface GameEngine : NSObject {
NSMutableArray *blockViews;
int numBlockRows;
int score;
}
@property (nonatomic, copy) NSMutableArray *blockViews;
@property int numBlockRows;
@property int score;
- (void) setup;
- (void) setupBlocks;
@end
//
// GameEngine.m
// Block Breaker
//
// Created by Chris Muench on 7/1/11.
// Copyright 2011 N/A. All rights reserved.
//
#import "GameEngine.h"
#import "Block.h"
#import "BlockView.h"
@implementation GameEngine
@synthesize blockViews;
@synthesize numBlockRows;
@synthesize score;
- (id) init
{
if ((self = [super init]))
{
self.blockViews = [[NSMutableArray alloc] init];
self.numBlockRows = 2;
self.score = 0;
}
return self;
}
- (void) setup
{
[self setupBlocks];
}
- (void) setupBlocks
{
float blockWidth = 10;
float blockHeight = 10;
float rowSpacing = 2;
float colSpacing = 2;
float currentX = 0;
float currentY=10;
float screenWidth = 200;
for (int rowCounter=0;rowCounter<self.numBlockRows;rowCounter++)
{
while(currentX <=screenWidth)
{
Block *curBlock = [[Block alloc] initWithWidth:blockWidth height:blockHeight];
BlockView *curBlockView = [[BlockView alloc] initWithFrame:CGRectMake(currentX, currentY, curBlock.width, curBlock.height)];
curBlockView.block = curBlock;
[self.blockViews addObject:curBlockView];
currentX+=blockWidth+colSpacing;
[curBlock release];
[curBlockView release];
}
currentX=0;
currentY+=blockHeight+rowSpacing;
}
}
@end
When you copy an NSMutableArray using the copy method, or a synthesized setter for which the property was specified as copy, you get an immutable copy, which means you essentially end up with a plain NSArray.* There is a method mutableCopy which will preserve the mutability, but I don't believe there's any way to specify that for a property.
If you want your array to be mutably copied when you set it, you'll have to write your own setter method, and specify that method in the property declaration.
@property (nonatomic, copy, setter=setBlockViewsByCopying) NSMutableArray * blockViews;
- (void) setBlockViewsByCopying: (NSMutableArray *)newBlockViews {
NSMutableArray * tmp = [newBlockViews mutableCopy];
[blockViews release];
blockViews = tmp;
}
A side note, as @InsertWittyName mentioned in a comment, your code initializing blockViews will create a leak, because you have two claims of ownership on the array you're creating -- one for the alloc and one for the retain or copy that you get using the property:
self.blockViews = [[NSMutableArray alloc] init];
// ^ One claim ^ Two claims
// Only one release later, when the property is set again!
// LEAK!
You should instead do:
self.blockViews = [NSMutableArray array];
// Creates an object you don't own which you then make one claim
// on using the setter
*Though as it is a class cluster, you really get some unspecified concrete subclass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With