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