2010-11-02 72 views
8

什么时候应该在我的iphone开发应用程序中使用self表达式?说我有2个字段:UITextField *text1;NSString *str1;保留和合成。什么时候应该使用“self”关键字?

当我访问这两个字段中的任何一个时,我应该何时以及何时不应该使用self.text1self.str1

回答

7

有某些情况下在那里的一般不提倡使用self. -expression访问属性。 通常你总是使用self一个属性的任何访问。这是最安全和简单的方法。特别是如果你使用保留,那么内存管理将为你完成。

从该规则的两个例外:

  • 任何init方法。
  • dealloc

在这两种情况下,你正在处理一个部分初始化对象。在这里使用setter或getter时可能会出现一些副作用 - 因为它们是方法,因此可能会被覆盖。

例如,采取一类A与已经由子类类B一个属性foo。子类B增加一个属性bar并覆盖设置者foo。现在您的init - 方法调用setFoo:,因为您使用self.foo = ...与一些初始值。但是,子类也会在此设置器中访问bar的值。但在这种情况下,可能会出现该条从未初始化并指向某些任意数据。 在init中调用setter我的原因崩溃,虽然在你自己的代码中可能不会太高。

8

self不是关键字,它是表达式。此外,您可以在任何时候使用它来直接引用自己或自己的方法或属性。 “我自己”当然是指您正在使用的课程的实例。

+1

所以它看起来像Java'this'表达式一样,除非处理同名变量 – binnyb 2010-11-02 17:48:33

+0

并不总是需要的。您是对的。 – 2010-11-02 17:53:15

+12

一个重要的区别是'self.str1 = @“abc”将使用访问器方法('setStr1:'),但是'str1 = @“abc”'不会。当使用具有'retain'属性的属性时,这种差异是至关重要的。所以,它实际上不是“与Java”相同“。 – 2010-11-02 17:59:42

0

我对Objective-C没有任何了解,但看起来很像this其他语言的关键字(如C++ ,C#,Java,PHP等)。如果是这样,那么我的建议是永远使用它。这样,如果你曾经(意外地)用相同的名称定义一个局部变量,那么你的代码不会中断。

但是,我还必须补充一点,这是一个有程序员社区里的火焰战争历史的宗教辩论。因此,请以一粒盐的形式接受这一建议,并使用对你最有意义的任何事情。只要保持一致即可。

+0

但是请注意,它不仅仅是Objective-C中的样式/可维护性问题 - 当使用具有getter/setter方法的属性时,省略“self”会绕过getter/setter;有一个真正的语义差异。 – 2010-11-02 18:03:16

+0

这就是我正在寻找的,不错 – binnyb 2010-11-02 18:05:49

+0

@David Gelhar - 对不起。告诉你我不知道。 :P – 2010-11-02 19:28:13

6

在您的示例中,当您使用self时,您不是直接访问实例变量,而是访问您定义的属性。

考虑这个例子:

@interface Foo : NSObject { 
    NSString *_bar; 
} 

@property (nonatomic, retain) NSString *bar; 

@end 

@implementation Foo 
@synthesize bar = _bar; 
-(void)baz { 
    _bar = @"ivar"; //accessing the ivar 
    self.bar = @"property"; //accessing the ivar via the property 
} 

@end 

一般来说,如果你使用性质,没有什么理由利用伊娃。这为您自动保留&发布值带来了额外的好处。

但是其他情况下,当您的属性将有一个readonly修饰符。在这些情况下,需要直接访问您的ivars以设置其值。

+0

我很困惑。 _foo和foo在哪里申报?他们真的应该在你的baz方法中做吧? – 2010-11-02 19:35:58

+0

对不起,我在自己的例子中犯了一个错字。修正 – 2010-11-02 19:53:43

5

如果你有一个自定义的getter,在方法调用中使用self也是一个好主意。使用核心数据的应用程序中的managedContext对象就是一个很好的例子。如果您通过self.managedContext来引用它,则可以覆盖该对象并将其设置为nil所需的对象。创建使用Core Data的应用程序时,请参阅由XCode生成的代码。

这里是由的XCode生成的代码的例子,实际上是:

@interface YourAppDelegate : NSObject <UIApplicationDelegate> 
{ 
@private 
    NSManagedObjectContext *managedObjectContext_; 
} 


@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 



@implementation ContractionTimerAppDelegate 

/** 
Returns the managed object context for the application. 
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
*/ 
- (NSManagedObjectContext *)managedObjectContext { 

    if (managedObjectContext_ != nil) { 
     return managedObjectContext_; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) { 
     managedObjectContext_ = [[NSManagedObjectContext alloc] init]; 
     [managedObjectContext_ setPersistentStoreCoordinator:coordinator]; 
    } 
    return managedObjectContext_; 
} 

@end 
1

如果你“合成”了变量,你应该“自我”。变量。小拇指规则

相关问题