【发布时间】:2010-11-02 17:43:58
【问题描述】:
什么时候应该在我的 iphone 开发应用程序中使用 self 表达式?假设我有 2 个字段:UITextField *text1; 和 NSString *str1; 保留和合成。
当我访问这两个字段中的任何一个时,我应该什么时候以及什么时候不应该使用self.text1 和self.str1?
【问题讨论】:
标签: iphone objective-c ios self
什么时候应该在我的 iphone 开发应用程序中使用 self 表达式?假设我有 2 个字段:UITextField *text1; 和 NSString *str1; 保留和合成。
当我访问这两个字段中的任何一个时,我应该什么时候以及什么时候不应该使用self.text1 和self.str1?
【问题讨论】:
标签: iphone objective-c ios self
self 不是关键字,而是表达式。此外,您可以在任何时候使用它来引用自己或直接引用自己的方法或属性。 “你自己”当然是指你正在操作的类的实例。
【讨论】:
this 表达式相同,除非处理具有相同名称的变量,否则并不总是需要它
self.str1 = @"abc" 将使用访问器方法 (setStr1:) 而str1 = @"abc" 不会。当使用带有retain 属性的属性时,这种区别很关键。所以,它真的不是“与 Java this 相同”。
在某些情况下,通常不鼓励使用self.-表达式来访问属性。 通常你 总是 使用 self 属性。 这是最安全和最简单的方式。特别是如果你使用了retain,那么内存管理将为你完成。
这条规则的两个例外:
init 方法。dealloc。在这两种情况下,您都在处理 部分初始化 对象。在此处使用 setter 或 getter 时可能会出现一些副作用——因为它们是方法,因此可能会被覆盖。
例如,获取一个类A,其属性foo 已被类B 子类化。子类B 添加了一个属性bar 并覆盖了foo 的setter。现在您的init 方法调用setFoo:,因为您使用了带有一些初始值的self.foo = ...。但是,子类也访问此 setter 中 bar 的值。但在这种情况下,可能会发生 bar 从未初始化并指向一些任意数据的情况。 在 init 中调用 setter 会导致崩溃,尽管在您自己的代码中概率可能不会太高。
【讨论】:
在您的示例中,当您使用 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
一般来说,如果您使用属性,几乎没有理由使用 ivar。这具有自动为您保留和释放价值的额外好处。
但在其他情况下,您的属性将具有 readonly 修饰符。在这些情况下,有必要直接访问您的 ivars 以设置它们的值。
【讨论】:
如果您有自定义 getter,有时在方法调用中使用 self 也是一个好主意。使用 Core Data 的应用程序中的 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
【讨论】:
如果你“综合”变量,你应该“自我”。变量。小经验法则
【讨论】:
我对objective-c一无所知,但这看起来很像其他语言(如C++、C#、Java、PHP等)的this关键字。如果是这样,那么我的建议是始终使用它。这样,如果您曾经(不小心)定义了同名的局部变量,您的代码就不会中断。
但是,我还必须补充一点,这在某种程度上是一场宗教辩论,在程序员社区中有着激烈的冲突历史。因此,对这个建议持保留态度,并使用任何对你来说最有意义的东西。保持一致即可。
【讨论】:
self”会绕过 getter/setter;存在真正的语义差异。