Пользовательский класс не реализует себя, когда я использую alloc / init или new в target-c - PullRequest
1 голос
/ 25 июля 2010

Я пишу свой первый пользовательский класс в target-c, и когда я пытаюсь реализовать экземпляр моего пользовательского класса, я получаю предупреждения, в которых говорится, что "машина может не отвечать на '+ alloc'" и "машина может не отвечать на" '+ init' ", и если я использую новый вместо этого, я получаю то же самое предупреждение, что он может не отвечать на новый. Кто-нибудь знает, почему это может быть? вот мой код:

#import <Foundation/Foundation.h>

@interface Car
{
    NSString *color;
    NSString *make;
int year;
}

- (void) print;
- (void) setColor: (NSString *) c;
- (void) setMake: (NSString *) m;
- (void) setYear: (int) y;


@end

@implementation Car

- (void) print
{
    NSLog(@"The $d Ford %@ is $@.", year, make, color);
}

- (void) setColor: (NSString *) c
{
    color=c;
}

- (void) setMake: (NSString *) m
{
    make=m;
}

- (void) setYear: (int) y
{
    year=y;
}


@end



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Car *car;

    car = [Car alloc];
    car = [Car init];

    [car setColor:@"blue"];
    [car setMake:@"Bronco"];
    [car setYear:1992];

    [car print];
    [car release];

    [pool drain];
    return 0;
}

Ответы [ 2 ]

2 голосов
/ 25 июля 2010

Похоже, у вас есть две проблемы;Во-первых, вы должны явно подкласс NSObject.Во-вторых, вы не вызываете init для выделенной памяти ... попробуйте следующие изменения:

@interface Car : NSObject
Car *car = [[Car alloc] init];

Вам также следует изучить использование свойств для вашего "setColor", "setMake" и т. Д.потому что вы не сохраняете или не освобождаете эти строки должным образом, и они будут протекать и вызывать неприятный беспорядок.Это действительно помогло мне включить статический анализатор (вы можете установить это в настройках проекта или нажать Apple-Shift-A для сборки с включенным анализатором).

РЕДАКТИРОВАТЬ:

ОКТаким образом, у принятого поста "Ответ" есть проблемы с памятью ... и не похоже, что он будет исправлен, так что вот и все ... правильно сделано:


#import <Foundation/NSObject.h>
#import <Foundation/Foundation.h>

@interface Car : NSObject
{
    NSString *color;
    NSString *make;
    int year;
}

@property (retain,readwrite) NSString * color;
@property (retain,readwrite) NSString * make;
@property (assign,readwrite) int year;

- (void) print;

@end

@implementation Car

@synthesize color;
@synthesize make;
@synthesize year;

- (void) print
{
    NSLog(@"The %d Ford %@ is %@.", year, make, color);
}

- (void) dealloc
{
    if (color)
        [color release];

    if (make)
        [make release];

    [super dealloc];
}

@end



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Car *car = [[Car alloc] init];

    car.color = @"blue";
    car.make = @"Bronco";
    car.year = 1992;

    [car print];
    [car release];

    [pool drain];
    return 0;
}

Если выхотите увидеть ПРОБЛЕМУ с принятым ответом, попробуйте эту модифицированную функцию main (используя оставшуюся часть его поста):



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Car *car = [[Car alloc] init];

    // Let's pretend we are getting a string from somewhere else:
    NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardInput];
    NSData *inputData;
    NSString *inputString;
    printf("Type the color: ");
    inputData = [fileHandle availableData];
    inputString = [[NSString alloc] initWithData: inputData encoding:NSUTF8StringEncoding];

    [car setColor:inputString];
    [car setMake:@"Bronco"];
    [car setYear:1992];

    // This works:
    [car print];

    // But now, the place that gave us the string releases it:
    [inputString release];

    // UT OH! Danger Will Robinson!
    [car print];

    [car release];

    [pool drain];
    return 0;
}

Вы можете использовать точно такой же метод main с моим опубликованным кодом, и он будет работатьбез ошибки, потому что класс Car сохранит строку и освободит ее, когда это будет сделано.(и setXXX: также допустимо при использовании свойств)

EDIT: компилятор перехитрил меня, когда я попытался продемонстрировать EXEC_BAD_ACCESS, используя статическую строку ... ха.

1 голос
/ 25 июля 2010

Прежде всего, ваш Car-класс должен наследоваться от NSObject (вот почему метод + alloc не найден)

<code></p>

<p>@interface Car : <strong>NSObject</strong>
{
    NSString *color;
    NSString *make;
int year;
}</p>

<ul>
<li>(void) print;</li>
<li>(void) setColor: (NSString *) c;</li>
<li>(void) setMake: (NSString *) m;</li>
<li>(void) setYear: (int) y;</li>
</ul>

<p>@end

Метод "init" - это метод экземпляра, который позволяет отправлять это сообщение только объекту, а не классу (Car). Обычный способ - отправить сообщение + alloc классу для создания экземпляра объекта этого класса. затем вы отправляете этому созданному объекту сообщение -init:

<code></p>

<p>Car *car;</p>

<p>car = [<strong>Car</strong> alloc];
car = [<strong>car</strong> init];

Или самый удобный способ:

<code></p>

<p>car = [[Car alloc] init];</p>

<p>

Метод alloc создает объект и резервирует для него память, для этого это CLASS-метод, потому что объекта еще нет. Затем сообщение инициализации отправляется созданному объекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...