#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
@interface CustomAnnotation : NSObject <MKAnnotation>
{
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subTitle;
}
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
- (id)initWithLocation:(CLLocationCoordinate2D)coords title:(NSString *)aTitle andSubtitle:(NSString*)aSubtitle;
@end
我正在做一个包含上述代码的教程。
我的问题:
请回答所有三个问题。
答案 0 :(得分:3)
1.
在大括号中定义变量之间的区别是什么 @property?
@interface XXX:YYY { place for ivars } place for properties. ivars prefixed with _(underscore) gets created automatically in new compiler. @end
2.
为什么我们需要在两个地方定义变量?
这是旧式的,现在只是完成了。只有@property
就够了。
3.
在.h和.m文件中声明#import之间的区别是什么?
如果你想要一些类的对象作为属性,你可以在.h中定义它,如果你只想在实现中而不是在.m中导入它。
如果将所有#imports放在头文件中,则不会有两个类 可以相互依赖,因为文件无法导入文件 进口它。如果将#import放在实现文件中,则打开 另一方面,问题就消失了。
答案 1 :(得分:2)
在大括号之间声明变量具有实际为变量创建存储的效果。
@property
声明将访问方法并自动为您生成支持ivar,这使得第一个声明变得多余。因此,您可以从花括号中删除声明,并保留您的属性声明。
自动合成的ivar将具有一个前导下划线,当您直接访问ivar或通过访问器时,它会更清晰,例如。
@property (nonatomic, strong) MyThing *myThing;
将在您的课程中直接使用
_myThing = [[MyThing alloc] init];
或通过访问者
[self setMyThing:[[MyThing alloc] init]];
通常,大多数时间通过访问器都是你想要的,除非你在被覆盖的访问器方法中。
有一段时间,@property
和@synthesize
只会为您生成访问者方法,您必须注意确保为其使用创建存储 - 声明卷曲之间的ivar括号。
然后事情继续前进,@property
和@synthesize
就是您所需要的,并且后备ivar将自动合成。
当前的游戏状态是@property
只需要(大多数情况下),@synthesize
是隐式完成的。
没有任何技术差异,语句只是抓取你要导入的文件的内容并将它们转储到它的位置。
您需要注意循环依赖
FileA | FileB
----------------+----------------
#import "FileB" | #import "FileA"
|
将成为
FileA |<-
----------------| \
#import "FileB" | /
#import "FileA" |-'
和
FileB |<-
----------------| \
#import "FileA" | /
#import "FileB" |-'
这两个文件将处于循环循环中,试图导入它们自己,例如这是行不通的。
因此,避免此问题的最简单方法是在标题中执行最少量的导入。
如果您需要在标题中引用类,请使用前向声明(@class
)
所以你最终得到了这个
@class MyClass
@interface MyOtherClass : NSObject
@property (nonatomic, strong) MyClass *mything;
@end
你基本上告诉编译器MyClass
存在,所以你可以引用它。
然后,您可以在实现文件中导入MyClass
的实际标头。
#import "MyOtherClass.h"
#import "MyClass.h"
@implementation MyOtherClass
@end
答案 2 :(得分:1)
1)在大括号中定义变量之间的区别是什么? @property?
因为@property
定义变量的态度以及它的可访问性限制,如果你不写@property
它也可以工作,但如果你想让编译器自动为变量创建getter和setter方法,那么使用{ {1}}和@property
在.m文件中。
2)为什么我们需要在两个地方定义变量?
第一个答案的后半部分包括答案。简要&#39;定义setter&amp; getter方法及其可访问性&#39;
3).h与.m文件中声明
@synthesize
之间的区别是什么?
如果您导入在.h文件中使用它,它将可用于该类的所有子类,而如果您导入.m文件,它将仅可用于(范围).m文件
答案 3 :(得分:1)
在大括号内,您可以声明所需的任何实例变量。在大括号之外是您声明@properties
的位置,它会自动生成对象的getter和setter,以及您在实现文件中定义的任何非私有方法。
正如@Anoop Vidya所提到的,在两个地方声明变量现在都是多余的,没有必要。
导入文件的一般经验法则:相互导入的文件会产生运行时错误。因此,请遵守以下规则:
如果您需要另一个类的实例变量,请使用
@class
导入标题中的其他类,然后在实现文件中导入#import
。如果您不需要从已创建的其他类创建ivar,那么只需
#import
将其添加到您的实现文件中。
如果您在执行这些步骤后仍然遇到相互依赖问题,那么您可能需要重新考虑您的设计。