将实例变量分配给自己

时间:2016-05-31 12:31:18

标签: ios objective-c

我的mTeacher课程中有一个实例变量School

@interface School : NSObject {
     Teacher *mTeacher;
}
@end

在实现文件中,我有方法- (Teacher *)getTeacher,它应该返回现有的教师实例(如果有)或创建一个并返回它:

- (Teacher *)getTeacher {
    if (mTeacher != nil) {
        return mTeacher;
    }
    return [[Teacher alloc] init];
}

可能有多个其他实例方法调用此方法来获取Teacher实例&分配给mTeacher实例变量:

- (void)methodOne {
   mTeacher = [self getTeacher];
   ...
}

- (void)methodTwo {
   mTeacher = [self getTeacher];
   ...
}

因此,如果其中一个方法已经分配了TeachermTeacher的实例,则调用[self getTeacher]的另一种方法最终会在mTeacher = mTeacher下面(因为{在这种情况下,{1}}方法只返回- (Teacher *)getTeacher。我的问题是,目标C是否很好?我的mTeacher方法有任何潜在问题吗?

4 个答案:

答案 0 :(得分:1)

看起来你想懒惰地实例化变量。

Objective-C中的常用模式是声明一个只读(非原子)属性,并使用后备实例变量进行初始化。

@interface School : NSObject 

@property (readonly, strong, nonatomic) Teacher *mTeacher;

@end

@implementation School
@synthesize mTeacher = _mTeacher;

- (Teacher *)mTeacher {
    if (!_mTeacher) {
        _mTeacher = [[Teacher alloc] init];
    }
    return _mTeacher;
}

@end

编辑:不使用属性直接访问实例变量:

@interface School : NSObject
{
  Teacher *mTeacher;
}

@end

@implementation School

- (Teacher *)mTeacher {
  if (!mTeacher) {
     mTeacher = [[Teacher alloc] init];
  }
  return mTeacher;
}

@end

但是,如果要显式使用getter而不是实例变量,则必须编写

[self mTeacher];

答案 1 :(得分:1)

方法是正确的,但有两个评论:

一个。你永远不可能拥有一个“没有教师”的方案,这意味着该属性为零 - 无论如何。

B中。显然,你从另一种语言的Objective-C开始:

  • 不要为“成员”使用m前缀。 (他们不是会员,但是伊娃。)

  • 请勿在界面中声明ivars。

  • 请勿为getter使用get前缀。

您可以使用vadian所提及的属性:

@interface School : NSObject 
@property (readonly, strong, nonatomic) Teacher *teacher; // without m
- (Teacher*)teacher; // *Alternatively* without @property
@end

@implementation School
// usually the ivar is created implicitly with the name _teacher. 
// However, you have a readonly property and overwrite all accessors 
// (in the case of a read only property there is only a getter) of the property, 
// no ivar will be created automatically. You have to do that explicitly.
{
    Teacher *_teacher;
}

- (Teacher *)teacher { // no m
  if (!_teacher) 
  {  
    _teacher = [[Teacher alloc] init];
  }
  return _teacher;
}
@end

此外,此代码不是线程安全的。

答案 2 :(得分:0)

目标c很好.. !!我认为你不应该对此有疑问,但你可以检查是否 - 否则,

 - (void)methodOne {

    if(!mTeacher){
    mTeacher = [self getTeacher];
    }
    ...
  }

因此,如果mTeacher不是nil,那么只会调用getTeacher

在目标c中,您可以使用property。它将设置它的getter和setter方法。或者您需要此对象在init方法中初始化一次。没必要这样做。

答案 3 :(得分:0)

这种方法没有错,为什么你不能在School init中创建Teacher对象。此外,如果您正在处理多线程环境,请确保您没有多次创建Teacher对象。