Iphone 申报财产的最佳方式是什么?
我们使用@property关键字声明属性,并在实现文件中合成它。我的问题是, 如果我使用@property关键字声明一个属性,并在接口块中声明一个同名变量,该怎么办?例如,考虑下面的代码, 接口:Iphone 申报财产的最佳方式是什么?,iphone,objective-c,ios,Iphone,Objective C,Ios,我们使用@property关键字声明属性,并在实现文件中合成它。我的问题是, 如果我使用@property关键字声明一个属性,并在接口块中声明一个同名变量,该怎么办?例如,考虑下面的代码, 接口: @interface myClass : NSObject { NSString *myClass_name; // LINE 1 } @property(nonatomic, retain) NSString *myClass_name; // LINE 2 @end 实施: @
@interface myClass : NSObject {
NSString *myClass_name; // LINE 1
}
@property(nonatomic, retain) NSString *myClass_name; // LINE 2
@end
实施:
@implementation myClass
@synthesize myClass_name // LINE 3
@end
@interface MyClass : NSObject {
float sameName;
float otherName;
}
@property float sameName;
@property float differentName;
@property float noDeclaredIvar;
@end
@implementation MyClass
@synthesize sameName;
@synthesize differentName=otherName;
@synthesize noDeclaredIvar;
@end
在第1行声明myClass_名称会有问题吗?像任何引用问题或任何不必要的内存消耗问题一样?不,事实上,声明这样的属性是需要的。您可以将您的声明替换为:
@interface MyClass : NSObject {
NSString *ivar;
}
@property (nonatomic, retain) NSString *myClass_name;
@end
然后将实现更改为
@implementation MyClass
@synthesize myClass_name = ivar;
@end
(如果不指定=some_ivar,它将假定ivar与属性具有相同的名称。)
您始终需要具有以下行:
- 财产声明(第2行)
- 物业综合(第3行)
在合成属性时,如果没有指定要使用的ivar(通过在末尾使用
=ivar
),它将假定存在一个与属性同名的ivar。事实上,没有像预期的那样声明属性。您可以将您的声明替换为:
@interface MyClass : NSObject {
NSString *ivar;
}
@property (nonatomic, retain) NSString *myClass_name;
@end
然后将实现更改为
@implementation MyClass
@synthesize myClass_name = ivar;
@end
(如果不指定=some_ivar,它将假定ivar与属性具有相同的名称。)
您始终需要具有以下行:
- 财产声明(第2行)
- 物业综合(第3行)
合成属性时,如果未指定要使用的ivar(通过在末尾使用
=ivar
),它将假定存在与属性同名的ivar。声明属性并合成它不会在您的案例中产生任何引用问题。
这样做将为类中的实例变量创建访问器和设置器方法。
如果属性中的变量名和类中声明的变量名相同,那么xcode将两者都作为单个变量引用
第3行和第4行是必须的。第1行是optiona声明属性并合成它不会在您的案例中产生任何引用问题。 这样做将为类中的实例变量创建访问器和设置器方法。 如果属性中的变量名和类中声明的变量名相同,那么xcode将两者都作为单个变量引用
第3行和第4行是必须的。第1行是optiona我从苹果公司的文档中获得了以下内容。我把它贴在这里,以便将来对某人有所帮助 运行时差异 通常,属性的行为在所有运行时都是相同的(请参见中)。有一个关键区别:现代运行时支持实例变量合成,而传统运行时不支持 要使
@synthesis
在旧版运行时工作,必须提供具有相同名称和兼容类型的属性的实例变量,或者在@synthesis
语句中指定另一个现有实例变量。对于现代运行时,如果不提供实例变量,编译器会为您添加一个实例变量。例如,给定以下类声明和实现:
@implementation myClass
@synthesize myClass_name // LINE 3
@end
@interface MyClass : NSObject {
float sameName;
float otherName;
}
@property float sameName;
@property float differentName;
@property float noDeclaredIvar;
@end
@implementation MyClass
@synthesize sameName;
@synthesize differentName=otherName;
@synthesize noDeclaredIvar;
@end
遗留运行时的编译器将在
@synthesis noDeclaredIvar处生成错误代码>而现代运行时的编译器将添加一个实例变量来表示noDeclaredIvar
,我从苹果的文档中获得了以下内容。我把它贴在这里,以便将来对某人有所帮助
运行时差异
通常,属性的行为在所有运行时都是相同的(请参见中)。有一个关键区别:现代运行时支持实例变量合成,而传统运行时不支持
要使@synthesis
在旧版运行时工作,必须提供具有相同名称和兼容类型的属性的实例变量,或者在@synthesis
语句中指定另一个现有实例变量。对于现代运行时,如果不提供实例变量,编译器会为您添加一个实例变量。例如,给定以下类声明和实现:
@implementation myClass
@synthesize myClass_name // LINE 3
@end
@interface MyClass : NSObject {
float sameName;
float otherName;
}
@property float sameName;
@property float differentName;
@property float noDeclaredIvar;
@end
@implementation MyClass
@synthesize sameName;
@synthesize differentName=otherName;
@synthesize noDeclaredIvar;
@end
遗留运行时的编译器将在@synthesis noDeclaredIvar处生成错误
现代运行时的编译器将添加一个实例变量来表示noDeclaredIvar
以下是面向对象的方式:
去极化特性
@interface DeclaringProperties : NSObject
// ivars and {} can be omitted
@property (nonatomic, readwrite, retain) NSString *normal;
@property (nonatomic, readwrite, retain) NSString *alias;
@property (nonatomic, readonly, retain) NSString *readonly;
- (id) initWithNormal:(NSString *)aNormal alias:(NSString *)alias;
@end
去极化特性
#import "DeclaringProperties.h"
// private interface
@interface DeclaringProperties ()
@property (nonatomic, readwrite, retain) NSString *readonly; // readwrite for self
@property (nonatomic, readwrite, retain) NSString *private;
@property (nonatomic, readwrite, retain) NSString *retain;
@end
#pragma mark -
@implementation DeclaringProperties
@synthesize normal, alias = _alias, readonly, private, retain;
// You can not use "normal" here;
// But you can still use "alias", and it is highlighted in XCode!
- (id) initWithNormal:(NSString *)aNormal alias:(NSString *)alias {
self = [super init];
if (self) {
self.normal = aNormal;
self.alias = alias;
self.readonly = @"readonly";
self.private = @"private";
// allocated(copied) variable for retained(copied) property should be released or autoreleased
NSString *alloc = [[NSString alloc] init];
self.retain = alloc;
[alloc release];
// or
self.retain = [[NSString alloc] init];
[self.retain release];
// or
self.retain = [[[NSString alloc] init] autorelease];
// I don't like ;)
retain = [[NSString alloc] init];
}
return self;
}
- (void) dealloc {
self.normal = nil;
self.alias = nil;
self.readonly = nil;
self.private = nil;
self.retain = nil;
[super dealloc];
}
@end
以下是面向对象的方式:
去极化特性
@interface DeclaringProperties : NSObject
// ivars and {} can be omitted
@property (nonatomic, readwrite, retain) NSString *normal;
@property (nonatomic, readwrite, retain) NSString *alias;
@property (nonatomic, readonly, retain) NSString *readonly;
- (id) initWithNormal:(NSString *)aNormal alias:(NSString *)alias;
@end
去极化特性
#import "DeclaringProperties.h"
// private interface
@interface DeclaringProperties ()
@property (nonatomic, readwrite, retain) NSString *readonly; // readwrite for self
@property (nonatomic, readwrite, retain) NSString *private;
@property (nonatomic, readwrite, retain) NSString *retain;
@end
#pragma mark -
@implementation DeclaringProperties
@synthesize normal, alias = _alias, readonly, private, retain;
// You can not use "normal" here;
// But you can still use "alias", and it is highlighted in XCode!
- (id) initWithNormal:(NSString *)aNormal alias:(NSString *)alias {
self = [super init];
if (self) {
self.normal = aNormal;
self.alias = alias;
self.readonly = @"readonly";
self.private = @"private";
// allocated(copied) variable for retained(copied) property should be released or autoreleased
NSString *alloc = [[NSString alloc] init];
self.retain = alloc;
[alloc release];
// or
self.retain = [[NSString alloc] init];
[self.retain release];
// or
self.retain = [[[NSString alloc] init] autorelease];
// I don't like ;)
retain = [[NSString alloc] init];
}
return self;
}
- (void) dealloc {
self.normal = nil;
self.alias = nil;
self.readonly = nil;
self.private = nil;
self.retain = nil;
[super dealloc];
}
@end
在这种情况下,我不需要第二行?@Justin Spahr Summers:我是否需要第二行?我真的不知道。请告诉我。我不明白你的问题,根据我的说法,你声明是正确的,只是在交易中放松一下section@Matt:谢谢你。。你的@synthesis myClass\u name=ivar
概念对我很有帮助。。我以前不知道。谢谢分享……也许你已经有了答案,但要明确你的问题:你不需要第1行。在这种情况下,我不需要第2行?@Justin Spahr Summers:我是否需要第2行?我真的不知道。请告诉我。我不明白你的问题,根据我的说法,你声明是正确的,只是在交易中放松一下section@Matt:谢谢你。。你的@synthesis myClass\u name=ivar
概念对我很有帮助。。我以前不知道。谢谢分享……也许你已经有了答案,但要明确你的问题:你不需要第1行。第4行是指哪一行?哦,对不起,我错了,我的意思是第2行和第3行是必须的。我还尝试省略第1行并运行代码。在您的情况下,如果您省略第1行,是否会导致任何错误?请在您的回答中将“第3行和第4行”更改为“第2行和第3行”。您所指的第4行是哪一行?哦,对不起,我的迷雾