Iphone 申报财产的最佳方式是什么?

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 实施: @

我们使用@property关键字声明属性,并在实现文件中合成它。我的问题是,

如果我使用@property关键字声明一个属性,并在接口块中声明一个同名变量,该怎么办?例如,考虑下面的代码,

接口:

@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行是哪一行?哦,对不起,我的迷雾