【问题标题】:custom class not implementing itself when i use alloc/init or new in objective-c当我在 Objective-C 中使用 alloc/init 或 new 时,自定义类没有实现自身
【发布时间】:2010-07-25 01:57:07
【问题描述】:

我正在用 Objective-C 编写我的第一个自定义类,当我尝试实现我的自定义类的实例时,我收到警告说“汽车可能无法响应 '+alloc'”和“汽车可能无法响应'+init'" 如果我​​使用 new 代替,我会收到相同的警告,它可能不会响应 new。有谁知道这可能是为什么?这是我的代码:

#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;
}

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    看起来你有两个问题;一,你可能应该明确地继承 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: 在使用属性时也有效)

    编辑:当我尝试使用静态字符串演示 EXEC_BAD_ACCESS 时,编译器比我聪明...哈哈。

    【讨论】:

    • @thyrgle;我认为他还没有到那个时候。除了格式说明符之外,他还有几个更重要的问题,比如他的内存管理。
    【解决方案2】:

    首先,你的 Car 类应该继承自 NSObject(这就是为什么找不到 +alloc 方法的原因)

    
    
    

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

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

    @end

    “init”方法是一种实例方法,意味着您只能将该消息发送到对象而不是类(汽车)。正常的方法是向类发送 +alloc 消息以实例化该类的对象。然后你向这个创建的对象发送 -init 消息:

    
    
    

    Car *car;

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

    或者最方便的方式:

    
    
    

    car = [[Car alloc] init];

    alloc 方法创建对象并为其保留内存,因为它是一个 CLASS 方法,因为还没有对象。然后将初始化消息发送到创建的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2011-11-05
      • 2021-03-12
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多