Objective-C中的构造函数

33

我试着运行下面的示例程序。

在类B中,我没有调用+(void)initialise和-(id)init方法,但它们自动被调用。

-(void)initialise方法是否等同于objective C中的默认构造函数?

[super init]是否指向NSObject?

如果我不使用-(id)init方法,将会收到一个警告,提示该类实现不完整。

ClassA.h

#import <Foundation/Foundation.h>

static int ab;

@interface ClassA : NSObject {
    int a;
}

+ (void) initialize;
- (id) init;
- (void) displayNumOfInstance;
- (void) disp;

@end

ClassA.m

#import "ClassA.h"

@implementation ClassA

+ (void) initialize
{
    ab=0;
}

- (id) init
{
    self = [super init];
    if (self!=nil) {
        ab++;
    }
    return self;
}

- (void) displayNumOfInstance
{
    NSLog(@"Number of instances of this class:%d",ab);
}

- (void) disp
{
    NSLog(@"The value is %d",ab);
}

@end

ClassB.h

#import <Foundation/Foundation.h>
#import "ClassA.h"

@interface ClassB : ClassA {

}

- (void) display;

@end

ClassB.m

#import "ClassB.h"

@implementation ClassB

- (void) display
{
    ab=20;
    NSLog(@"The value ab is %d",ab);
}

@end
#import <Foundation/Foundation.h>
#import "ClassA.h"

int main (int argc, const char * argv[]) {
    ClassA *a = [[ClassA alloc]init];
    [a disp];
    [a release];

    ClassB *b = [[ClassB alloc]init];
    [b display];
    [b release];

    ClassA *a1 = [[ClassA alloc]init];
    [a1 disp];
    [a1 release];

    ClassB *b1 = [[ClassB alloc]init];
    [b1 display];
    [b1 release];

    return 0;
}

输出:

2011-04-30 15:31:42.490 class2[1674:a0f] 1
2011-04-30 15:31:42.493 class2[1674:a0f] The value ab is 20
2011-04-30 15:31:42.494 class2[1674:a0f] 2
2011-04-30 15:31:42.495 class2[1674:a0f] The value ab is 20
1个回答

61

默认构造方式通常以以下格式开始:-init或任何变体,例如-initWithFrame:

+initialize方法是一个类方法(静态方法),在您的应用程序启动时至少调用一次。您可以使用此方法来初始化对所有类实例有用的静态变量。例如,此方法可能有助于初始化类的共享缓存或共享查找映射。

对于NSObject类,-init方法是指定的初始化器,但对于其他类,情况可能不同。苹果公司使用NS_DESIGNATED_INITIALIZER宏在其类头文件中记录指定的初始化器。例如,UIView子类应该重写-initWithFrame:-initWithCoder:,因为这些方法被标记为指定的初始化器。

当子类化并实现自定义指定初始化器时,不要忘记初始化超类。例如,假设我们有一个UIView子类,具有自定义指定初始化器-initWithFrame:title:,我们将其实现如下:

// A custom designated initializer for an UIView subclass. 
- (id)initWithFrame:(CGRect)frame title:(NSString *)title 
{
    // Initialize the superclass first. 
    //
    // Make sure initialization was successful by making sure 
    // an instance was returned. If initialization fails, e.g. 
    // because we run out of memory, the returned value would
    // be nil.
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Superclass successfully initialized.
        self.titleLabel.text = title
    }
    return self;
}

// Override the designated initializer from the superclass to 
// make sure the new designated initializer from this class is 
// used instead.
- (id)initWithFrame:(CGRect)frame
{
    return [[self alloc] initWithFrame:frame title:@"Untitled"];
}

可以在 Apple Developer 网站上找到有关初始化的更多详细信息:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接