Objective-C多个初始化程序 [英] Objective-C Multiple Initialisers

查看:120
本文介绍了Objective-C多个初始化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于在Objective-C类中创建多个初始化程序,我有一个简单的问题. 基本上,我有一个表示数据库(用户)中的一行的类.我目前有一个初始化程序,该初始化程序根据用户UserID(也是数据库内的主键)来初始化类,当传递UserID时,该类将使他们连接到Web服务以解析结果并返回初始化到相应行的对象在数据库中.

I have a simple question about creating multiple initialisers within an objective-c class. Basically I have a class that represents a single row in my database (users). I currently have an initialiser which initialises the class based upon the users UserID (which is also the primary key within the database), when passed the UserID the class will them connect to a webservice parse the results and return an object initialised to the corresponding row in the database.

在此数据库中,有许多唯一字段(用户名和电子邮件地址),我也希望能够基于这些值来初始化我的对象.但是我不确定如何拥有多个初始化程序,我所阅读的所有内容都表明我可以自由地拥有多个初始化程序,只要每个都调用指定的初始化程序即可.如果有人可以帮我解决这个问题,那就太好了.

Within this database are a number of unique fields (username and emailaddress), I would also like to be able to initialise my object based upon these values. But I am unsure of how to have more than one initialiser, everything I have read states that I am free to have multiple initialisers, as long as each calls the designated initialiser. If someone could help me out with this, that would be great.

我的初始化代码如下:

- (id) initWithUserID:(NSInteger) candidate {
    self = [super init];
    if(self) {
        // Load User Data Here
        NSString *soapMessage = [NSString stringWithFormat:
                                 @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                                 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
                                 "<soap:Body>\n"
                                 "<GetByUserID xmlns=\"http://tempuri.org/\">\n"
                                 "<UserID>%d</UserID>\n"
                                 "</GetByUserID>\n"
                                 "</soap:Body>\n"
                                 "</soap:Envelope>\n", candidate
                                 ];
        NSLog(@"%@",soapMessage);

        // Build Our Request
        NSURL *url = [NSURL URLWithString:@"http://photoswapper.mick-walker.co.uk/UsersService.asmx"];
        NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
        NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];

        [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
        [theRequest addValue: @"http://tempuri.org/GetByUserID" forHTTPHeaderField:@"SOAPAction"];
        [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
        [theRequest setHTTPMethod:@"POST"];
        [theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

        NSError *WSerror;
        NSURLResponse *WSresponse;

        webData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&WSresponse error:&WSerror];

        xmlParser = [[NSXMLParser alloc] initWithData: webData];
        [xmlParser setDelegate: self];
        [xmlParser setShouldResolveExternalEntities: YES];
        [xmlParser parse];
    }
    return self;
}

根据Laurent的评论,我尝试实现自己的解决方案,如果您能通过此解决方案告知我任何明显的陷阱,我将不胜感激:

Following from Laurent's comment, I have tried to implement my own solution, I would be grateful if you could inform me of any obvious gotcha's with this solution:

我不太确定我理解您的意思,我已经尝试实现自己的解决方案.如果您能告诉我您的想法,我将不胜感激:

I am not totally sure I understand you're meaning, I have tried to implement my own solution. I would be grateful if you could let me know what you think:

- (id) init {
    self = [super init];
    if(self){
        // For simplicity I am going to assume that the 3 possible
        // initialation vectors are mutually exclusive.
        // i.e if userName is used, then userID and emailAddress
        // will always be nil
        if(self.userName != nil){
            // Initialise object based on username
        }
        if(self.emailAddress != nil){
            // Initialise object based on emailAddress
        }
        if(self.userID != 0){ // UserID is an NSInteger Type
            // Initialise object based on userID
        }
    }
    return self;
}
- (id) initWithUserID:(NSInteger) candidate {
    self.userID = candidate;
    return [self init];
}
- (id) initWithEmailAddress:(NSString *) candidate {
    self.emailAddress = candidate;
    return [self init];
}
- (id) initWithUserName:(NSString *) candidate {
    self.userName = candidate;
    return [self init];
}

致谢

推荐答案

指定的初始化程序的定义为 Objective-C编程指南:初始化程序的实现已被详细记录.

The designated initializer's definition is here. It is a strong requirement to ensure that your instances are consistent whatever the initializer you use. For a full reference, see the Objective-C Programming Guide: the initializer implementation is well documented.

修复@NSResponder报告的错字

Edit 2: Fix typo reported by @NSResponder

我认为在设置成员后调用init是不可靠的.成员可能具有怪异的值,这些值将无法通过初始化测试.

I think calling init after setting the member is not reliable. Members may have weird values that will fail the test for initialization.

一种更好的方法是先调用"init"方法(这将为成员设置默认值),然后再设置成员.这样,您的所有初始值设定项都具有相同的代码结构:

A better way to do it is to call the "init" method first (which will set default values for members) and then to set the member. This way, you have the same code structure for all your initializers:

- (id) init {
    self = [super init];
    if(self){
        self.userID = 0;
        self.userName = nil;
        self.emailAddress = nil;
    }
    return self;
}

- (id) initWithUserID:(NSInteger) candidate {
    self = [self init];
    if(self){
        self.userID = candidate;
    }
    return self;
}

这篇关于Objective-C多个初始化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆