【问题标题】:i try to understand initializers in obj-c and i can't我试图理解 obj-c 中的初始化程序,但我不能
【发布时间】:2012-01-02 19:16:52
【问题描述】:

我试图了解如何使用简单的 init 函数,但我不知道我在哪里犯了错误。有人可以帮忙吗?

矩形.h

@interface Rectangle : NSObject
{
    int width;
    int height;
}
-(id)initObject;
@end

矩形.m

@implementation Rectangle

-(id)initObject{
    if (self = [super init]) {
        height = 5;
        width = 7;
    }
    return self;
}    

@end

我在 ViewController.h 中导入 Rectangle.h,声明 *rect 对象并在 .m 中执行(?运行?)initObject。

ViewController.h

#import <UIKit/UIKit.h>
#import "Rectangle.h"
@interface ViewController : UIViewController
{
    Rectangle *rect;
}
@end

ViewController.m

-(void)viewDidLoad
{
    rect = [[Rectangle alloc] initObject];
    NSLog(@"%@", rect);

    [super viewDidLoad];

}

initObject 返回我:

 2011-11-21 09:43:02.625 initializers[43693:f803] <Rectangle: 0x6ab1660>

【问题讨论】:

  • 为什么是“if (self = [super init]) {?”
  • 没有问题,看起来不错。如果你想看height 和width 写NSLog(@"%d, %d", rect.height, rect.width);
  • 我在许多示例中看​​到它只是看起来像。我还看到:self = [super init];如果(自我){...
  • @Brogrammer:经典的初始化风格使用if ((self = [super init])) { ... }。这是 Cocoa 多年来一直使用的风格。最近有self = [super init]; if (self) { ... }的趋势,不过这个在功能上是一样的,虽然我个人认为是浪费一行。
  • 看这个视频:youtube.com/watch?v=plrjQwomUtI&feature=relmfu。没关系。

标签: objective-c class import initialization


【解决方案1】:

我可以看到您的代码的唯一问题是您无缘无故地将初始化程序称为-initObject。它根本不带任何参数,所以你真的应该像系统中其他所有无参数初始化程序一样调用它-init。

至于日志输出,我想你的困惑在于它说&lt;Rectangle: 0x6ab1660&gt;。这是完全正常的。 -description(返回此输出的方法)的默认实现是对象的类名,后跟对象的地址。换句话说,-[NSObject description] 很可能实现如下:

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@: %p>",
                                      NSStringFromClass([self class]),
                                      self];
}

这意味着你的对象的实例变量不会被打印出来。许多内置类在记录时会打印它们的实例变量,但这是专门为该类实现的,不是通用机制。如果你想验证你的Rectangle 对象是否正确,你可以像这样实现-description:

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@: %p width=%d, height=%d>",
                                      NSStringFromClass([self class]),
                                      self,
                                      width,
                                      height];
}

【讨论】:

  • 另一个让我们其他人变得多余的答案!我现在要回去工作了... :)
  • 谢谢你的帮助,我现在明白了; ) 所以,当我使用 init 函数时,我应该使用 -description。
  • @TomaszSzulc 不一定,如果您希望自定义类在作为stringWithFormat 的参数传递时默认打印不同,则只需覆盖description。正如其他人所提到的,您仍然可以在description 之外测试这些变量。 TLDR:您没有必须将description 与init 函数一起使用。
【解决方案2】:

没有错误!由于您的 Rectangle 类没有 description 方法,因此调用 NSLog(@"%@", rect); 将返回对象的类,后跟其在内存中的地址。

如果你想打印矩形的width 和height,你可以使用类似的东西:

在 Rectangle.h 中

@interface Rectangle : NSObject 
{
    int width;
    int height;
}
-(id)initObject;

@property int width, height;
@end

在 Rectangle.m 中

@implementation Rectangle

@synthesize width, height;

-(id)initObject{
    if (self = [super init]) {
        height = 5;
        width = 7;
    }
    return self;
}    

@end

然后调用

NSLog(@"width=%d, height=%d", [rect width], [rect height]);

【讨论】:

    猜你喜欢
    • 2012-04-09
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2019-06-18
    相关资源
    最近更新 更多