簡體   English   中英

Objective-C語法; 是班級類別嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM