Chris Muench
Chris Muench

Reputation: 18318

Error: "Unrecognized selector" when using addObjects: on an NSMutableArray

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

Upvotes: 2

Views: 2521

Answers (3)

ingconti
ingconti

Reputation: 11646

Copy should retain, If I remember correctly.

Anyway using copying cannot be optimal, every time you call the accessor (set), you got a copy, and, as well pointed out above, is immutable.

Adding is fine, but remember to release the array when done.

Upvotes: 0

jscs
jscs

Reputation: 64002

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.

Upvotes: 10

Legolas
Legolas

Reputation: 12325

Did you retain your array ??

Upvotes: -1

Related Questions