什麼時候應該在我的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