2013-01-01 51 views
1

我有几个关于Objective-C中变量/对象声明的问题,我希望你能帮助我更好地理解一些东西。Objective-C变量/对象声明

  1. 我知道,给一个变量的@property声明可以让你从其他类访问它,如果你不打算使用它,它自己在课堂之外,有没有使用呢?

  2. 我经常在示例代码中看到变量和对象只声明使用@property而不是直接在@interface中声明。为什么?

  3. 我还看到有人在使用@synthesize时,做了类似var = _var;的事情。怎么来的?

  4. 当引用对象和变量时,是否有任何理由,例如做self.var.而不是var.

我认为这就是所有,希望你能帮我解决这些奥秘(也许还有其他人),谢谢。

+0

MHM我怕你应该看看一个初学者的书(没有进攻) - 这是一个有点广阔对于这个网站的国际海事组织(这当然可能是错的^^) –

+0

这主要是在这里覆盖:http://stackoverflow.com/q/843632/937822 – lnafziger

回答

3
  1. @property和合成,甚至私下使用,给你预构建 getter和setter。这就是我使用它们的原因。

  2. 在最近的Xcode中,您会得到一个为您提供的合成,因此您 可以将@property与@synthesize单独对待。

  3. 下划线别名可以让你的名字堆栈变量同样没有 歧义,e.g ....

    // say my class contains a property called foo, alias _foo. 
    - (void)initWithFoo:(id)foo { 
        self = [self init]; 
        if (self) { 
         _foo = foo; // assign the param to the instance var 
        } 
        return self; 
    } 
    
  4. 这是使用getter和setter的init和 的dealloc外面很好的做法。吸气剂和吸附剂“夹断”访问 属性到您可能想要添加行为的单个位置。 例如,常见的做法是使用吸气剂懒惰 初始化...

    // this code assumes ARC, otherwise for retained properties without arc, you'll need to add release and retain code here and if you replace the default setter 
    - (SomeType *)bar { 
        if (!_bar) { 
         _bar = [[SomeType alloc] init]; 
        } 
        return _bar; 
    } 
    
+1

“//分配给属性的参数”是不是很正确 - 您将参数分配给实例变量。它不使用属性设置器。此外,当不在ARC下时,它应该是'_foo = [foo retain]'或'_foo = [foo copy]',只是为了让任何人阅读。 – Chuck

+0

谢谢,@Chuck - 我会编辑评论。还会指出我假设ARC。 – danh

1
  1. 当您使用@property是合成*你能避免书写“样板”的代码,如复制或锁定来访问原子。随着ARC的引入,这一功能的重要性大大降低。
  2. 无需在最新的Xcode中编写@synthesize,您可以使用很少或不需要额外编码的属性。由于属性比变量更“未来的证明”,因为你可以在setter中执行验证并在getter中执行计算,所以几乎没有理由使用“普通”变量。
  3. 在最新的Xcode中不需要使用@synthesize。如果您看到很多@synthesize,则可能是您正在阅读“旧代码”(超过6个月)。
  4. 不,没有理由这样做与变量。据说为了清晰起见,一些商店要求程序员这样做。我不会对此发表评论,因为这是一个偏好问题。如果您决定这样做,您应该在整个代码库中一致地执行此操作。
    *明确地通过@synthesize或隐式使用最新的Xcode。
2
  1. 您还可以访问您不声明为属性的变量。物业只是一条捷径。一种告诉编译器自动为该变量创建getter和setter(accessor)方法的方法。您有时在括号中看到的标志是更改访问方法的实际实现的附加选项。
  2. 因为在这种情况下,实例变量会在编译时自动添加到您的类中。除了额外的下划线前缀(_var)之外,该变量的名称将与您的属性相同。
  3. 这允许您更改自动生成的实例变量的名称。等号后面是财产;实例变量在右侧。你也可以自己声明实例变量,如果它不同于属性的名称,你必须这样分配它。
  4. 使用self.var将使用访问器方法(无论它们是否自动添加,或者您自己实现它们)。例如,如果你想懒洋洋地加载一个对象,你可以实现一个getter自己来检查,如果该对象已经存在,如果不创建它,并将其返回:

    // Assuming you defined @property (nonatomic) MyClass *var; in the header 
    - (MyClass *)var { 
        if (!_var) { 
         _var = [[MyClass alloc] init]; 
        } 
        return _var; 
    } 
    

    现在你可以使用点语法访问:

    [self.var doSomething]; 
    

    这将调用上面定义的getter。如果变量是nil(尚未使用),则首先进行初始化。如果您刚刚使用实例变量...

    [_var doSomething]; 
    

    ...您将得到不同的结果。如果_varnil,则该消息将被忽略(无错误,崩溃)。这是因为你直接访问变量,而不是通过访问器方法。当然,如果您确定该对象将被初始化,或者在nil时处理该案例,那么您可以直接使用它。