现在的位置: 首页 > 综合 > 正文

编程笔记(objective-c :关于属性)

2013年09月11日 ⁄ 综合 ⁄ 共 4066字 ⁄ 字号 评论关闭

转载请标明出处:blog.csdn.net/zhangxingping

关于属性

        在C++中,通常需要编写Getter和Setter方法来获取或者是设置实例变量的值。这两种方法需要在程序中显示的完成。这种方式在Objective-C中也是适用的。但是Objective-C提供了一种更为便捷的方式来完成这种功能。它就是属性。和C++中的显示的Getter和Setter方法相比,属性机制使得Getter函数和Setter来的更容易和更简化。

Objectivc-C中的属性是通过关键字@property来声明的。

例如,有类如下:

Student.h文件:

#import <Foundation/Foundation.h>
 
 
@interface Student : NSObject
{
@private
    NSString * name;  //学生的姓名
    float math;       //数学科目的成绩
    float english;    //英语科目的成绩 
   
}
 
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish;
 
-(NSString *)getName;
-(float)getMath;
-(float)getEnglish;
 
@end

Student.m文件:

#import "Student.h"
 
@implementation Student
 
- (id)init
{
    self = [super init];
    if (self)
    {
        name = nil;
        math = 0;
        english = 0;
    }
   
    return self;
}
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish
{
    self = [super init];
    if (self)
    {
        name = aName;
        math = scoreMath;
        english = scoreEnglish;
    }
   
    return self;
}
 
-(NSString *)getName
{
    return name;
}
 
-(float)getMath
{
    return math;
}
 
-(float)getEnglish
{
    return english;
}
 
- (void)dealloc
{
    [super dealloc];
}
 
@end

main.m文件如下:

 #import <Foundation/Foundation.h>

#import "Student.h"
 
int main (int argc, const char * argv[])
{
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
    Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f];
   
    NSLog(@"Name:%@",[p getName]);
    NSLog(@"Math:%f",[p getMath]);
    NSLog(@"Math:%f",[p getEnglish]);   
   
    [p release];
 
    [pool drain];
    return 0;
}

上面程序的输出结果如下:

Name:Mark

Math:80.000000

Math:100.000000

上面的程序是通过C++中的方式来编写Getter方法来获取私有的实例变量的值。这些个Getter方法实现虽然简单,但是必需有程序员显示书写来完成。应用属性机制后,程序如下:

Student.h文件:

#import <Foundation/Foundation.h>
 
@interface Student : NSObject
{
@private
    NSString * name;  //学生的姓名
    float math;       //数学科目的成绩
    float english;    //英语科目的成绩 
   
}
 
@property NSString * name;
@property float math;
@property float english;
 
 
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish;
 
//-(NSString *)getName;
//-(float)getMath;
//-(float)getEnglish;
 
@end

Student.m文件:

#import "Student.h"
@implementation Student
 
@synthesize name;
@synthesize math;
@synthesize english;
 
- (id)init
{
    self = [super init];
    if (self)
    {
        name = nil;
        math = 0;
        english = 0;
    }
   
    return self;
}
 
-(id)initWithName:(NSString*)aName math:(float)scoreMath english:(float)scoreEnglish
{
    self = [super init];
    if (self)
    {
        name = aName;
        math = scoreMath;
        english = scoreEnglish;
    }
   
    return self;
}
 
//-(NSString *)getName
//{
//    return name;
//}
//
//-(float)getMath
//{
//    return math;
//}
//
//-(float)getEnglish
//{
//    return english;
//}
//
//- (void)dealloc
//{
//    [super dealloc];
//}
 
@end

main.m文件如下: 

#import <Foundation/Foundation.h>
#import "Student.h"
 
int main (int argc, const char * argv[])
{
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
    Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f];
   
//  NSLog(@"Name:%@",[p getName]);
//  NSLog(@"Math:%f",[p getMath]);
//  NSLog(@"Math:%f",[p getEnglish]);   
    NSLog(@"Name:%@",p.name);
    NSLog(@"Math:%f",p.math);
    NSLog(@"Math:%f",p.english);  
   
    [p release];
 
    [pool drain];
    return 0;
}

程序的输出如下:

Name:Mark

Math:80.000000

Math:100.000000

可见属性机制使得程序更加简洁明了。

上面程序中引入了新的关键字@synthesize,这个关键字告诉编译器自动为其后面的属性生成Getter()和Setter()方法。需要注意的一点是虽然在描述上适用的是“自动生成Getter()和Setter()方法”,但是实际上我们并看不到生成的对应代码。需要明确的是编译器自动生成的Getter方法:name(),math(),english()以及Sette方法:setName(), setMath(), setEnglish()的调用完全和普通的方法是一样的。例如我们可以修改上面的main()函数如下:

 

#import <Foundation/Foundation.h>
#import "Student.h"
 
int main (int argc, const char * argv[])
{
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
    Student * p = [[Student alloc] initWithName:@"Mark" math:80.0f english:100.00f];
   
//  NSLog(@"Name:%@",[p getName]);
//  NSLog(@"Math:%f",[p getMath]);
//  NSLog(@"Math:%f",[p getEnglish]);
   
   
//    NSLog(@"Name:%@",p.name);
//    NSLog(@"Math:%f",p.math);
//    NSLog(@"Math:%f",p.english);  
   
    [p setName:@"Tony"];
    [p setMath:99.0f];
    [p setEnglish:89.98f];   
 
    NSLog(@"Name:%@",[p name]);
    NSLog(@"Math:%f",[p math]);
    NSLog(@"Math:%f",[p english]);  
 
 
   
    [p release];
 
    [pool drain];
    return 0;
}

程序输出为:

Name:Tony

Math:99.000000

Math:89.980003

        上面的程序在Xcode中编译后,会在@property NSString * name;代码的所在行头看到一个黄色的叹号,这表明编译器在该行代码处给出了编译警告。单击该黄色叹号可以看到给出的警告信息:“No 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed”和“Default property attribute 'assign' not appropriate for non-gc object”。警告信息的意思是:“没有明确指出应该是assign还是retain或者是copy,却省的是assign”和“缺省得属性设置assign不适合非gc对象
”,那么这两个警告信息的含义具体是什么呢?assign,retian,copy又分别代表什么含义呢?什么是gc对象呢?什么是非gc对象呢?这些问题见后文描述。

抱歉!评论已关闭.