【问题标题】:Constructor in Objective-CObjective-C 中的构造函数
【发布时间】:2011-04-30 11:18:53
【问题描述】:

我在下面尝试这个示例程序。

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

-(void)initialise 是否等于目标 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

class2.m

#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

【问题讨论】:

    标签: objective-c


    【解决方案1】:

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

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

    对于NSObject-init 方法是指定的初始化器,但对于其他类,这可能会有所不同。 Apple 使用 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 网站:

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-11
      • 2011-03-09
      • 2011-11-30
      相关资源
      最近更新 更多