[英]Objective-C syntax; is it a class category?
我正在閱讀有關Objective-C中核心數據的教程,並且無法理解以下語法:
@interface RootViewController : UITableViewController <CLLocationManagerDelegate> {
NSMutableArray *eventsArray;
NSManagedObjectContext *managedObjectContext;
CLLocationManager *locationManager;
UIBarButtonItem *addButton;
}
@property (nonatomic, retain) NSMutableArray *eventsArray;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, retain) UIBarButtonItem *addButton;
@end
在這里,我們在實現文件中聲明了四個屬性,據我所知,這四個屬性是私有的。 大括號內到底發生了什么? 為什么將這些變量放在那里? 而且,這是一個類擴展嗎? 我在這里看到()
丟失,所以可能不是。 那么這種語法叫什么?
它不是一個類別,它只是一個名為RootViewController
的類,該類擴展了UITableViewController
並實現了協議CLLocationManagerDelegate
。
大括號->
通常,如果您沒有在花括號中創建iVars
,默認情況下,它們會以underscore as prefix
創建。 這是由編譯器完成的。
但是在這里,您明確地說過,該ivar應該沒有下划線(_)。
您應該按照以下說明進行synthesize
,否則會發出警告。
@synthesize eventsArray= eventsArray;
這只是RootViewController
類的常規定義, @interface
不一定必須位於頭文件中,私有類(不應/不需要在其他地方訪問)也可以直接在中定義.m
文件。
花括號中的定義只是RootViewController
類的常規實例變量。
您擁有的稱為類接口。 它只是您的程序文件的.h文件。 如果您想要一個班級類別,只需執行
@interface RootViewController (CategoryName)
並擴展為.m類型
@interface RootViewController ()
@end
@implementation
花括號之間的變量:
{
NSMutableArray *eventsArray;
NSManagedObjectContext *managedObjectContext;
CLLocationManager *locationManager;
UIBarButtonItem *addButton;
}
只是通常的變量。
對於使用@property基本字定義的變量:
@property (nonatomic, retain) NSMutableArray *eventsArray;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, retain) UIBarButtonItem *addButton;
創建訪問器和更改器方法。 您還可以為括號中的變量定義選項。 另外,您可以在.m
文件中使用基本字詞@synthesize
來獲取它們的本地同義詞,例如
@synthesize addButton = myLovelyButton;
那么您可以在.m
文件中使用myLovelyButton
而不是addButton
這兩個定義都不屬於該類別。 對於定義類別,只需鍵入如下代碼:
@interface <#className#> (<#categoryName#>)
{
//optional variables here
int i;
NSString *s;
}
//optional variables here
@property NSString *str;
//optional methods here
-(void)doSomething;
@end
然后,您可以實現您的方法並使用以下變量:
@implementation <#className#> (<#categoryName#>)
-(void)doSomething
{
int i = 0;
str = @"blah";
s = @"wow";
NSLog(@"%i - %@ - %@",i,str,s);
}
@end
使用該方法將您的方法添加到現有類中。
@interface或@implementation之后方括號內的變量是實例變量。 這些是與類的每個實例關聯的變量,因此可以在實例方法中的任何位置訪問。
如果不放在方括號中,則聲明全局變量。 如果在@implementation指令之前或之后,則在任何括號塊之外聲明的任何變量將是全局變量。 全局變量是邪惡的,需要不惜一切代價避免使用(可以聲明全局常量,但要避免使用全局變量),尤其是因為它們不是線程安全的(因此可能會產生導致調試混亂的錯誤)。
@interface YourClass : ParentClass
{
// Declare instance variables here
int ivar1;
}
// declare instance and class methods here, as well as properties (which are nothing more than getter/setter instance methods)
-(void)printIVar;
@end
// .m
int someGlobalVariable; // Global variable (bad idea!!)
@implementation YourClass
int someOtherGlobalVariable; // Still a bad idea
-(void)printIVar
{
NSLog(@"ivar = %d", ivar1); // you can access ivar1 because it is an instance variable
// Each instance of YourClass (created using [[YourClass alloc] init] will have its own value for ivar1
}
除了可以在@interface之后聲明它們之外,只有現代編譯器允許您在類擴展(.m實現文件中的@interface YourClass())或@implementation中聲明實例變量(仍放在方括號中)。在您的.h。 好處是可以通過在.m文件中而不是在.h文件中聲明它們來向類的外部用戶隱藏這些實例變量,因為類的用戶無需了解的內部編碼詳細信息您的課程,但只需要知道公共API。
最后一條建議:Apple不再建議使用實例變量,而是越來越多地建議直接使用@property,並讓編譯器(顯式使用@synthesize指令,或隱式使用現代LLVM編譯器)生成內部支持變量。 這樣一來,您通常根本不需要聲明實例變量,因此可以在@interface指令后省略空{}:
// .h
@interface YourClass : ParentClass
// Declare methods and properties here
@property(nonatomic, assign) int prop1;
-(void)printProp;
@end
// .m
@implementation YourClass
// @synthesize prop1; // That's even not needed with modern LLVM compiler
-(void)printProp
{
NSLog(@"ivar = %d", self.prop1);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.