什么时候应该在我的iphone开发应用程序中使用self
表达式?说我有2个字段:UITextField *text1;
和NSString *str1;
保留和合成。什么时候应该使用“self”关键字?
当我访问这两个字段中的任何一个时,我应该何时以及何时不应该使用self.text1
和self.str1
?
什么时候应该在我的iphone开发应用程序中使用self
表达式?说我有2个字段:UITextField *text1;
和NSString *str1;
保留和合成。什么时候应该使用“self”关键字?
当我访问这两个字段中的任何一个时,我应该何时以及何时不应该使用self.text1
和self.str1
?
有某些情况下在那里的一般不提倡使用self.
-expression访问属性。 通常你总是使用self
一个属性的任何访问。这是最安全和简单的方法。特别是如果你使用保留,那么内存管理将为你完成。
从该规则的两个例外:
init
方法。dealloc
。在这两种情况下,你正在处理一个部分初始化对象。在这里使用setter或getter时可能会出现一些副作用 - 因为它们是方法,因此可能会被覆盖。
例如,采取一类A
与已经由子类类B
一个属性foo
。子类B
增加一个属性bar
并覆盖设置者foo
。现在您的init
- 方法调用setFoo:
,因为您使用self.foo = ...
与一些初始值。但是,子类也会在此设置器中访问bar
的值。但在这种情况下,可能会出现该条从未初始化并指向某些任意数据。 在init中调用setter我的原因崩溃,虽然在你自己的代码中可能不会太高。
self
不是关键字,它是表达式。此外,您可以在任何时候使用它来直接引用自己或自己的方法或属性。 “我自己”当然是指您正在使用的课程的实例。
我对Objective-C没有任何了解,但看起来很像this
其他语言的关键字(如C++ ,C#,Java,PHP等)。如果是这样,那么我的建议是永远使用它。这样,如果你曾经(意外地)用相同的名称定义一个局部变量,那么你的代码不会中断。
但是,我还必须补充一点,这是一个有程序员社区里的火焰战争历史的宗教辩论。因此,请以一粒盐的形式接受这一建议,并使用对你最有意义的任何事情。只要保持一致即可。
但是请注意,它不仅仅是Objective-C中的样式/可维护性问题 - 当使用具有getter/setter方法的属性时,省略“self”会绕过getter/setter;有一个真正的语义差异。 – 2010-11-02 18:03:16
这就是我正在寻找的,不错 – binnyb 2010-11-02 18:05:49
@David Gelhar - 对不起。告诉你我不知道。 :P – 2010-11-02 19:28:13
在您的示例中,当您使用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以设置其值。
我很困惑。 _foo和foo在哪里申报?他们真的应该在你的baz方法中做吧? – 2010-11-02 19:35:58
对不起,我在自己的例子中犯了一个错字。修正 – 2010-11-02 19:53:43
如果你有一个自定义的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
如果你“合成”了变量,你应该“自我”。变量。小拇指规则
所以它看起来像Java'this'表达式一样,除非处理同名变量 – binnyb 2010-11-02 17:48:33
并不总是需要的。您是对的。 – 2010-11-02 17:53:15
一个重要的区别是'self.str1 = @“abc”将使用访问器方法('setStr1:'),但是'str1 = @“abc”'不会。当使用具有'retain'属性的属性时,这种差异是至关重要的。所以,它实际上不是“与Java”相同“。 – 2010-11-02 17:59:42