ios 目标 C:如何编写实例化自定义初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6514001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Objective C: How to Write a Instantiating Custom Init
提问by Derek
Very basic question, but I have an error in my code that can only be answered by one assumption: my class isn't being instantiated!
非常基本的问题,但我的代码中有一个错误,只能通过一个假设来回答:我的类没有被实例化!
I haven't written much in Objective C in some time, and I was never really good, so please point out even the most painfully obvious.
我已经有一段时间没有用 Objective C 写太多东西了,而且我从来都不是很好,所以即使是最明显的痛苦也请指出。
I am using:
我在用:
ObjectSelectionViewController *length = [[ObjectSelectionViewController alloc] initWithMeasureType:0];
ObjectSelectionViewController *mass = [[ObjectSelectionViewController alloc] initWithMeasureType:1];
ObjectSelectionViewController *volume = [[ObjectSelectionViewController alloc] initWithMeasureType:2];
NSLog(@"%@", [length measurementType]);
NSLog(@"%@", [mass measurementType]);
NSLog(@"%@", [volume measurementType]);
The NSLogs return whichever measurement was assigned last, regardless of the separate allocs and inits.
NSLogs 返回最后分配的测量值,而不管单独的分配和初始化。
Here is the constructor of the ObjectSelectionViewController class:
这是 ObjectSelectionViewController 类的构造函数:
#import "ObjectSelectionViewController.h"
@implementation ObjectSelectionViewController
NSString *measurementType;
-(ObjectSelectionViewController*) initWithMeasureType:(int)value
{
switch (value) {
case 0: // Length
measureType = @"Length";
break;
case 1: // Mass
measureType = @"Mass";
break;
case 2: // Volume
measureType = @"Volume";
break;
}
return self;
}
-(NSString*) measurementType
{
return measureType;
}
Thanks for the help, it's driving me crazy!
感谢您的帮助,这让我发疯了!
回答by jscs
You need to make measureType
an instance variable, so that each object of this type that you create has its own copy:
您需要创建measureType
一个实例变量,以便您创建的每个这种类型的对象都有自己的副本:
@interface ObjectSelectionViewController : NSViewController {
NSString * measureType; // Declare an NSString instance variable
}
- (id) initWithMeasureType: (int)value;
@end
As it is, there is only one copy of the variable, and every time you instantiate a new object, its value changes. Since each instance is referring to the same copy, they all get the same value:
事实上,变量只有一个副本,每次实例化一个新对象时,它的值都会改变。由于每个实例都指向同一个副本,它们都获得相同的值:
ObjectSelectionViewController *length = [[ObjectSelectionViewController alloc] initWithMeasureType:0];
NSLog(@"%@", [length measurementType]); // Prints "Length"
ObjectSelectionViewController *mass = [[ObjectSelectionViewController alloc] initWithMeasureType:1];
NSLog(@"%@", [length measurementType]); // Prints "Mass"
You also need to change your init...
method as mentioned by other answerers:
您还需要更改init...
其他回答者提到的方法:
- (id) initWithMeasureType: (int)value {
// Call superclass's initializer
self = [super init];
if( !self ) return nil;
switch (value) {
case 0: // Length
measureType = @"Length";
break;
case 1: // Mass
measureType = @"Mass";
break;
case 2: // Volume
measureType = @"Volume";
break;
}
return self;
}
Since you are assigning a literal string to the instance variable, you do not need to worry about managing its memory; if you were doing anything more complicated, you would probably do well by declaring a property.
Another note: initializer methods should always return id
, a generic object pointer, to allow subclasses to work properly.
由于您将文字字符串分配给实例变量,因此您无需担心管理其内存;如果你正在做任何更复杂的事情,你可能会通过声明一个property 来做得很好。另一个注意事项:初始化方法应始终返回id
一个通用对象指针,以允许子类正常工作。
回答by Hollance
You need to call [super init]
first, like this:
你需要先打电话[super init]
,像这样:
-(id) initWithMeasureType:(int)value
{
if ((self = [super init]))
{
switch (value) {
case 0: // Length
measureType = @"Length";
break;
case 1: // Mass
measureType = @"Mass";
break;
case 2: // Volume
measureType = @"Volume";
break;
}
}
return self;
}
回答by Tommy
Constructors are a convention in Objective-C rather than a language feature. So, for example, there's no automatic calling of parent constructors (just like you wouldn't expect any other overridden method to call its parent implementations). Similarly, the names used for constructors are just conventions, so the compiler knows nothing of init
. With that in mind, what you actually want as your constructor is:
构造函数是 Objective-C 中的约定而不是语言特性。因此,例如,没有自动调用父构造函数(就像您不希望任何其他覆盖方法调用其父实现一样)。同样,用于构造函数的名称只是约定,因此编译器对init
. 考虑到这一点,您真正想要的构造函数是:
-(id) initWithMeasureType:(int)value
{
if((self = [super init]))
{
switch (value) {
case 0: // Length
measureType = @"Length";
break;
case 1: // Mass
measureType = @"Mass";
break;
case 2: // Volume
measureType = @"Volume";
break;
}
}
return self;
}
Assuming measureType is an instance variable (declared as part of the interface, generally speaking) and not a global then that should do what you want.
假设 measureType 是一个实例变量(一般来说,声明为接口的一部分)而不是全局变量,那么它应该做你想做的。
回答by Dancreek
In your custom init method you just need to start with:
在您的自定义 init 方法中,您只需要从以下内容开始:
self = [super init];
回答by sony
- (id) initWithMeasureType: (int)value {
// Call superclass's initializer
self = [super init];
if( !self ) return nil;
switch (value) {
case 0: // Length
measureType = @"Length";
break;
case 1: // Mass
measureType = @"Mass";
break;
case 2: // Volume
measureType = @"Volume";
break;
}
return self;
}
}