在iPhone开发/Objective-C中初始化实例变量
作为iPhone/Objective-C开发的新手,我想问这个问题,以确保在不同的场景中正确初始化实例变量。下面,我将介绍一些场景,如果有人看到任何错误的操作,请让我知道。(注意:对于我的示例,我将使用“instanceVariable”作为我们要初始化的实例变量,它是类“InstanceVariableClass”的对象。) 场景1:在非UIViewController类中初始化 a) 新分配 在初始值设定项中,可以直接访问变量(即不通过其属性)并分配它。当您调用alloc时,新创建的对象将自动保留,这将在以后与getter和setter方法一起使用时非常有效。您不希望使用属性分配变量,即在iPhone开发/Objective-C中初始化实例变量,iphone,objective-c,ios,cocoa-touch,design-patterns,Iphone,Objective C,Ios,Cocoa Touch,Design Patterns,作为iPhone/Objective-C开发的新手,我想问这个问题,以确保在不同的场景中正确初始化实例变量。下面,我将介绍一些场景,如果有人看到任何错误的操作,请让我知道。(注意:对于我的示例,我将使用“instanceVariable”作为我们要初始化的实例变量,它是类“InstanceVariableClass”的对象。) 场景1:在非UIViewController类中初始化 a) 新分配 在初始值设定项中,可以直接访问变量(即不通过其属性)并分配它。当您调用alloc时,新创建的对象将自
self.instanceVariable=[[InstanceVariableClass alloc]init]
或者您将保留它两次(一次在setter方法中,一次使用alloc)
b) 参数
再次单击OK,直接访问初始值设定项中的实例变量。因为您没有分配变量,只是想拥有一个传递给您的副本,所以需要让它显式地保留自己。如果您使用了setter方法,它会为您保留它,但希望避免访问初始值设定项中的属性
c) 方便法
使用方便的方法返回新对象时,还需要显式保留,原因与参数相同。便利方法(如果正确实现)将自动删除它生成的新对象,因此我们不必担心双重保留它
场景2:在UIViewController类中初始化
a) 新分配
在UIViewController中,您希望在viewDidLoad方法中初始化实例变量,以采用延迟加载的做法,或者仅在需要变量的确切时刻加载变量。在初始值设定项之外,直接访问变量是不好的做法,因此我们现在将使用合成setter方法来设置变量。您不希望使用setter方法分配变量,即[self-setInstanceVariable]=[[InstanceVariableClass alloc]init]
或者您将保留它两次(一次在setter方法中,一次使用alloc)。因此,最佳做法是创建一个新的临时变量,初始化临时变量,将实例变量设置为临时变量,然后释放临时变量。synthesissetter方法将为您保留该变量
b) 方便法
在初始化器方法之外初始化实例变量时,我们可以简单地使用setter方法来设置并保留生成的对象。便利方法(如果正确实现)将自动删除它返回的对象,因此我们不必担心双重保留它
这就是我目前所知道的。如果有人能在我的推理中发现任何缺陷,或者想到我忘记包括的任何其他场景,请让我知道。谢谢。您提供的所有示例都非常有效 然而,许多有经验的obj-c程序员宁愿从不直接访问实例变量,除非是在他们的set/get方法中(如果您使用
@property
和@synthesis
声明实例变量,这些方法甚至可能不存在),除非有必要避免一些性能瓶颈
所以,我的构造函数通常是这样的:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.instanceArray = [NSArray array];
}
return self;
}
但是,如果分析代码时发现set/get方法和autoreleass池占用了太多的CPU时间或RAM,我有时会选择完全按照您的方式编写代码。首先,Objective-C没有类变量;只是实例变量 第二,你想得太多了。内存管理规则相对简单,与setter/getter方法和/或对象创建正交。在
-init*
方法中使用setter是一个问题,因为如果覆盖setter,可能会触发副作用。然而,如果您在-init*
和-dealoc
期间出现了setter/getter副作用,那么您可能会遇到更糟糕的体系结构问题
autorelease
不过是每个线程延迟的release
。一般来说,您不必担心通过各种方便的对象实例创建方法创建的autorelease
d对象,但在某些情况下,autorelease压力可能是一个真正的性能问题,使用显式+alloc/set/-release可能很有用这样想:
- 当您对iVar进行直接分配时,您不会离开调用作用域,因此,分配可能会消耗调用作用域中维护的+1保留计数(可能)
- 当通过方法调用(点语法或其他)进行赋值时,在调用范围中维护的保留计数与setter方法中发生的事情无关。这两个需要独立维护各自的保留计数增量。也就是说,如果setter想要保留对象,它将保留它。调用方独立维护其保留计数
- Senario 1 a)
这是无用的c
- (id)initWithFrame:(CGRect)frame object(InstanceVariableClass*) theInstanceVariable {
self = [super initWithFrame:frame];
if (self) {
instanceVariable = [theInstanceVariable retain];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
instanceVariable = [[InstanceVariableClass returnInitializedObject] retain];
}
return self;
}
- (void) viewDidLoad // or - (void) loadView if you implemented your view programmatically
{
[super viewDidLoad];
InstanceVariableClass *tempInstanceVariable = [[InstanceVariableClass alloc] init];
[self setInstanceVariable: tempInstanceVariable];
[tempInstanceVariable release];
}
- (void) viewDidLoad // or - (void) loadView if you implemented your view programmatically
{
[super viewDidLoad];
[self setInstanceVariable: [InstanceVariableClass instanceVariableClassWithInt:1]];
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.instanceArray = [NSArray array];
}
return self;
}