Objective-C语法;它是一个类别?

时间:2014-02-24 12:50:00

标签: ios objective-c core-data

我正在阅读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

我们在这里有四个属性在实现文件中声明,据我所知,它们是私有的。大括号内究竟发生了什么?为什么要把这些变量放在那里?而且,它是一个类扩展吗?我看到()在这里丢失,所以可能不是。这种语法叫什么呢?

5 个答案:

答案 0 :(得分:2)

它不是一个类别。它只是一个名为RootViewController的类,它扩展了UITableViewController并实现了协议CLLocationManagerDelegate

来到你​​的大括号 - &gt;
通常,如果您不在花括号中创建iVars,则默认情况下会使用underscore as prefix创建它们。这是由编译器完成的。

但是在这里,你明确地说,ivar应该没有下划线(_)。

你应该synthesize如下所示,否则它会发出警告。

@synthesize eventsArray= eventsArray;

答案 1 :(得分:0)

这只是RootViewController类的常规定义,@interface不一定必须在头文件中,私有类(不应该/不需要访问)其他地方)也可以直接在.m文件中定义。

花括号中的定义只是RootViewController类的常规实例变量。

答案 2 :(得分:0)

你所拥有的是所谓的类接口。它只是程序文件的.h文件。如果你想要一个班级类别,那就去做

@interface RootViewController (CategoryName) 

和扩展名,在.m类型

@interface RootViewController () 
@end 
@implementation

答案 3 :(得分:0)

花括号之间的变量:

{
    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;

创建了访问器和mutator方法。您还可以在护腕中定义这些变量的选项。另外,您可以使用@synthesize文件中的基本单词.m获取本地同义词,例如

@synthesize addButton = myLovelyButton;

然后您可以使用myLovelyButton文件中的.m代替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

使用它将方法添加到现有类中。

答案 4 :(得分:0)

@interface或@implementation之后的括号内的变量是实例变量。这些变量与您的类的每个实例相关联,因此可以在实例方法中的任何位置访问。

如果不放括号,则声明全局变量。在任何括号块之外声明的任何变量都将是一个全局变量,这些变量在@implementation指令之前或之后。全局变量是邪恶的,需要不惜一切代价避免(你可以声明全局常量,但避免使用全局变量),特别是因为它们不是线程安全的(因此可能会产生调试乱七八糟的错误)。 p>

@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

}

只有现代编译器允许您在类扩展(.m实现文件中的@interface YourClass())或@implementation中声明实例变量(仍在括号中),以及在之后声明它们的可能性.h中的@interface。通过在.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);

}