我想我在Objective-C上写了一本坏书。它说把我要使用的变量放在接口括号内的其他类中,然后声明同一个属性。
@interface appDelegate : NSObject <UIApplicationDelegate> {
NSNumber *myNumberOtherClassesCanUse;
}
@property (nonatomic, retain) NSNumber *myNumberOtherClassesCanUse;
然而,我看到另一个回答的问题让我觉得我没有把它们放在括号内,所以我试过了,它仍然可以正常工作。
我买了另一本书并且它也没有解释,所以有人可以告诉我或指出我何时必须将它们放在括号中并使它们成为属性的文档?
答案 0 :(得分:4)
一个冗长而复杂的答案:
类字段,接口括号内的东西:
@interface MyClass : SomeSuperclass
{
int someNumber_; /* this stuff */
}
将实际字节添加到对象中。在所有的绒毛之下,一个客观的C类实际上只是一个大的C结构;这些是该结构的领域。 (您甚至可以使用->
样式C指针语法来获取它们,尽管编译器会在没有@public
的情况下对您大喊大叫;访问这些字段的正确方法是通过名称像任何其他变量一样。)
属性声明,如:
@property (nonatomic, assign, readwrite) int someNumber;
是一对方法声明的obj-C 2.0简写,如:
-(int)someNumber;
-(void)setSomeNumber:(int)newNumber;
这对你的班级没有任何好处;它只是告诉全世界,这里有一些可以在这个类上执行的操作。按照惯例,像这样的方法应该获取和设置字段值,或者至少表现得像它们那样。使用这样的方法可以使用obj.prop
和obj.prop = val
点语法来调用它们。
合成指令:
@synthesize someNumber;
可选择在运行时为您创建这些方法,使用标准的内置行为(通过“非原子,分配”的东西), AND 可选地创建一个相同名称的字段来获取和设置。像@synthesize someNumber = someNumber_;
这样的指令将创建的字段命名为“someNumber_”。如果你在@interface块中声明了这样一个字段,就像我上面那样,它会使用那个字段;否则它会悄悄地插入自己的适当字段。这个安静的字段插入是自4.x模拟器以来的新行为;在此之前,您必须在@interface {}块中声明所有字段。句号。
总结:@interface {...}描述了对象的物理字段; @property()...描述了你的对象应该被使用的方式;和@synthesize是实现基本getter / setter并在需要时插入额外字段的简写。我通常让@synthesize做它的事情,并将我的@interface {}块留空,直到我确实需要明确声明一个字段,通常是用调试器查看它。
[截至最新的SDK,上述部分内容已过时。特别是,@ synthesize现在是可选的,并且可以在.m文件的@implementation
中声明实例变量。]
答案 1 :(得分:1)
当您使用@interface
和@property
时,通常不必将它们放在@synthesize
括号中,因为如果它没有检测到,则合成将为您创建变量支持在课堂上宣布的ivar。
辉煌的iOS recipes
书指出iOS设备运行时总是具有此功能,但它只被添加到iOS 4中的模拟器中。因此,考虑到模拟器在开发中被大量使用,它可能只是一种习惯那个坚持了一些。
并在The Objective-C Programming Language
有一个关键区别:现代运行时支持实例变量合成,而遗留运行时则不支持。
答案 2 :(得分:0)
相信你的编译器,而不是你的书。