Ошибка: «Нераспознанный селектор» при использовании addObjects: на NSMutableArray - PullRequest
2 голосов
/ 01 июля 2011

При выполнении

[self.blockViews addObject:curBlockView];

Я получаю ошибку

2011-07-01 13: 35: 26.240 Прерыватель блоков [42061: 207] - [__ NSArrayI addObject:]: нераспознанный селектор отправлен в экземпляр 0x4e037a0

Я довольно новичок в Objective-C. Это что-то в моем init методе?

//
//  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

Ответы [ 3 ]

10 голосов
/ 01 июля 2011

Когда вы копируете NSMutableArray с использованием метода copy или синтезированного сеттера, для которого свойство было указано как copy, вы получаете неизменяемую копию, что означает, что вы по сути делас простым NSArray. * Существует метод mutableCopy, который сохранит изменчивость, но я не верю, что есть способ указать это для свойства.

Если вы хотите, чтобы ваш массив был копируемым образом изменен при установке, вам придется написать собственный метод установки и указать этот метод в объявлении свойства.

@property (nonatomic, copy, setter=setBlockViewsByCopying) NSMutableArray * blockViews;

- (void) setBlockViewsByCopying: (NSMutableArray *)newBlockViews {
    NSMutableArray * tmp = [newBlockViews mutableCopy];
    [blockViews release];
    blockViews = tmp;
}

Дополнительное замечание, как @InsertWittyName упомянул в комментарии, ваш код, инициализирующий blockViews, создаст утечку, потому что у вас есть две заявки на владение созданным массивом - одна для allocи один для retain или copy, который вы получаете, используя свойство:

self.blockViews = [[NSMutableArray alloc] init];
//  ^ One claim                    ^ Two claims
// Only one release later, when the property is set again!
// LEAK!

Вместо этого вы должны сделать:

self.blockViews = [NSMutableArray array];
// Creates an object you don't own which you then make one claim
// on using the setter

* Хотя, как этокластер классов, вы действительно получаете неуказанный конкретный подкласс.

0 голосов
/ 01 июня 2012

Копия должна сохраниться, если я правильно помню.

В любом случае использование копирования не может быть оптимальным, каждый раз, когда вы вызываете метод доступа (набор), вы получаете копию, и, как было указано выше, она неизменна.

Добавление нормально, но не забудьте освободить массив, когда закончите.

0 голосов
/ 01 июля 2011

Вы retain ваш массив ??

...