Objective-C 中的构造函数

Posted

技术标签:

【中文标题】Objective-C 中的构造函数【英文标题】:Constructor in Objective-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

【问题讨论】:

【参考方案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 网站:

Object Initialization

Multiple Initializers

【讨论】:

以上是关于Objective-C 中的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C类的构造函数和析构函数

如何将 Objective-C initXXX 方法绑定到具有相同类型参数的 Xamarin.iOS 构造函数?

swift中构造方法和Kvc

对于Objective-C初学者而言,用instancetype和id来定义一个简易的构造函数,到底区别在哪?

Swift 构造过程

Swift之深入解析构造过程