ObjC第二节:属性声明、类的组合
2015-08-11 20:30
399 查看
属性声明、类的组合
1、属性声明
1.1 声明属性让编译器自动合成setter和getter方法,使用关键字@property和@synthesize
1.2 在头文件中,@property int count; 等价于- (int) count; -(void)setCount:(int)newCount;
在实现文件中,@synthesize count; 等价于 - (int) count{ return count; } - (void) setCount:(int)newCount { count = newCount; }
1.3 @property 可以将同类型的实例变量写在一行,不同类型需分开写;@synthesize 则无论类型
1.4 @property (参数) 类型 名字;
2、参数
2.1 三类参数:读写属性(readwrite,readonly) setter语意(assign,retain, copy) 原子性(atomic, nonatomic)
2.2 readwrite 产生setter、getter方法(默认)
readonly 只产生getter方法,没有setter方法
assign 直接赋值,适用于基本数据类型(默认)
retain 旧空间释放再进行retain操作,适用于OC对象
copy 旧空间释放再进行copy操作,适用于NSString等不可变对象(?)
nonatomic 禁止多线程,提高性能
atomic 提供多线程安全,防止在写未完成的时候被另一个线程读取,造成数据错误。如果使用多线程,有时会出现两个线程相互等待对方导致死锁,使用atomic防止出现此情况,但会消耗一定资源。(加锁,解锁)(默认)
2.3
3.1 @class 。。。; 前向声明,提高程序运行效率,需要在.m中再用import导入
3.2 Has-A为组合关系,Is-A是继承关系
A、属性声明
Toy.h
#import <Foundation/Foundation.h>
@interface Toy : NSObject
@property (nonatomic) int num;
@property (nonatomic, retain) NSString * color;
//- (int) num;
//- (NSString *) color;
//- (void) setNum:(int)_num andColor:(NSString *)_color;
- (void) print;
@endToy.m
#import "Toy.h"
@implementation Toy
@synthesize num, color;
//- (int) num
//{
// return num;
//}
//- (NSString *) color
//{
// return color;
//}
//- (void) setNum:(int)_num andColor:(NSString *)_color
//{
// num = _num;
// color = _color;
//}
- (void) print
{
NSLog(@"num: %d, color: %@", num, color);
}
@endBaby.h
#import <Foundation/Foundation.h>
#import "Toy.h"
@interface Baby : NSObject
@property (nonatomic, retain) Toy * toy;
@property (nonatomic, retain) NSString * name;
@property (nonatomic) int age;
//- (Toy *) toy;
//- (NSString *) name;
//- (int) age;
//- (void) setToy:(Toy *)_toy;
//- (void) setName:(NSString *)_name andAge:(int)_age;
- (void) print; //不声明只实现,就是私有方法,只能在.m中使用
//- (void) dealloc; //系统自动调用,就算不声明只实现,也可以正常使用
@end
////assign
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// toy = _toy;
//}
////retain
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}
////copy
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}Baby.m
#import "Baby.h"
@implementation Baby
@synthesize name, age, toy;
//- (Toy *) toy
//{
// return toy;
//}
//- (NSString *) name
//{
// return name;
//}
//- (int) age
//{
// return age;
//}
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}
//- (void) setName:(NSString *)_name andAge:(int)_age
//{
// name = _name;
// age = _age;
//}
- (void) print
{
NSLog(@"name: %@, age: %d", name, age);
[toy print];
}
- (void) dealloc
{
[toy release];
[super dealloc];
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Baby.h"
int main()
{
@autoreleasepool
{
Baby * b = [[Baby alloc] init]; //初始化的Baby含有指针toy,但为nil,因为没有新建Toy对象并赋值
b.name = @"AAA";
b.age = 5;
b.toy.color = @"紫";
b.toy.num = 5;
[b print];
NSLog(@"num: %d, color: %@", b.toy.num, b.toy.color);
Toy * t1 = [[Toy alloc] init];
t1.num = 10;
t1.color = @"红";
[t1 print];
Toy * t2 = [[Toy alloc] init];
t2.num = 20;
t2.color = @"绿";
[t2 print];
b.toy = t1;
[b print];
b.toy = t2;
[b print];
b.toy.color = @"紫";
b.toy.num = 5;
NSLog(@"num: %d, color: %@", b.toy.num, b.toy.color);
[b release];
[t1 release];
[t2 release];
}
}
B、组合
XYPoint.h
#import <Foundation/Foundation.h>
@class Circle;
@interface XYPoint : NSObject
{
int x;
int y;
}
@property int x, y;
- (void) setX:(int)xVal andY:(int)yVal;
@endXYPoint.m
#import "XYPoint.h"
@implementation XYPoint
@synthesize x, y;
- (void) setX:(int)xVal andY:(int)yVal
{
x = xVal;
y = yVal;
}
@endCircle.h
#import <Foundation/Foundation.h>
//#import "XYPoint.h"
@class XYPoint;
@interface Circle : NSObject
4000
{
int radius;
XYPoint * origin;
}
@property int radius;
- (XYPoint *) origin;
- (void) setOrigin : (XYPoint *)pt;
- (int) area;
- (int) perimeter;
@end
//objective-c中,当一个类使用到另一个类时,并且在类的头文件中需要创建被引用的指针时,如下面代码:
//A.h文件
//#import "B.h"
//@interface A : NSObject {
// B *b;
//}
//@end
//为了简单起见:A类是引用类,B类是被引用类,这里先不考虑A类的实现文件。
//通常引用一个类有两种办法:一种是通过#import方式引入;另一种是通过@class引入;
//这两种的方式的区别在于:
//1、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息;
//2、使用@class方式由于只需要被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所以需要使用#importl来包含被引用类的头文件;
//3、通过上面2点也很容易知道在编译效率上,如果有上百个头文件都#import了同一 个文件,或者这些文件依次被#improt(A->B, B->C,C->D…),一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了;
//4、对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,B类的代码:
//#import "A.h"
//@interface B : NSObject {
// A *a;
//}
//@end
//当程序运行时,编译会报错,
//当使用@class在两个类相互声明,就不会出现编译报错。
//由上可知,@class是放在interface中的,只是在引用一个类,将这个被引用类作为一个类型,在实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类。Circlr.m
#import "Circle.h"
#import "XYPoint.h"
@implementation Circle
@synthesize radius;
- (XYPoint *) origin
{
return origin;
}
- (void) setOrigin : (XYPoint *)pt
{
origin = pt;
}
- (int) area
{
return 3.14 * radius * radius;
}
- (int) perimeter
{
return 2 * 3.14 * radius;
}
@endmain.m
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h" //如果不包含会报错,XYPoint是外部定义的类
int main()
{
@autoreleasepool
{
XYPoint * p = [[XYPoint alloc] init];
p.x = 2;
p.y = 2;
Circle * c = [[Circle alloc] init];
c.radius = 2;
NSLog(@"%d",c.radius);
c.origin = p;
NSLog(@"%@",c.origin);
NSLog(@"%d, %d",c.origin.x, c.origin.y);
NSLog(@"%d, %d",[[c origin] x], [[c origin] y]);
}
return 0;
}
1、属性声明
1.1 声明属性让编译器自动合成setter和getter方法,使用关键字@property和@synthesize
1.2 在头文件中,@property int count; 等价于- (int) count; -(void)setCount:(int)newCount;
在实现文件中,@synthesize count; 等价于 - (int) count{ return count; } - (void) setCount:(int)newCount { count = newCount; }
1.3 @property 可以将同类型的实例变量写在一行,不同类型需分开写;@synthesize 则无论类型
1.4 @property (参数) 类型 名字;
2、参数
2.1 三类参数:读写属性(readwrite,readonly) setter语意(assign,retain, copy) 原子性(atomic, nonatomic)
2.2 readwrite 产生setter、getter方法(默认)
readonly 只产生getter方法,没有setter方法
assign 直接赋值,适用于基本数据类型(默认)
retain 旧空间释放再进行retain操作,适用于OC对象
copy 旧空间释放再进行copy操作,适用于NSString等不可变对象(?)
nonatomic 禁止多线程,提高性能
atomic 提供多线程安全,防止在写未完成的时候被另一个线程读取,造成数据错误。如果使用多线程,有时会出现两个线程相互等待对方导致死锁,使用atomic防止出现此情况,但会消耗一定资源。(加锁,解锁)(默认)
2.3
<span style="font-size:12px;">//assign get - (Toy *) toy; - (Toy *) toy { return toy; } set - (void) setToy:(Toy *)_toy; - (void) setToy:(Toy *)_toy { toy = _toy; } //retain get - (Toy *) toy; - (Toy *) toy { return toy; } set - (void) setToy:(Toy *)_toy; - (void) setToy:(Toy *)_toy { if (toy != _toy) //避免自赋值 { [toy release]; //旧空间释放,引用计数器-1 toy = [_toy retain]; //引用计数器+1,最终指向同一内存空间 } } //copy get - (Toy *) toy; - (Toy *) toy { return toy; } set - (void) setToy:(Toy *)_toy; - (void) setToy:(Toy *)_toy { if (toy != _toy) { [toy release]; toy = [_toy retain]; //复制该内存存储的内容,赋给一个新建的对象,最终指向不同的内存空间,但内容相同 } }</span>3、类的组合
3.1 @class 。。。; 前向声明,提高程序运行效率,需要在.m中再用import导入
3.2 Has-A为组合关系,Is-A是继承关系
A、属性声明
Toy.h
#import <Foundation/Foundation.h>
@interface Toy : NSObject
@property (nonatomic) int num;
@property (nonatomic, retain) NSString * color;
//- (int) num;
//- (NSString *) color;
//- (void) setNum:(int)_num andColor:(NSString *)_color;
- (void) print;
@endToy.m
#import "Toy.h"
@implementation Toy
@synthesize num, color;
//- (int) num
//{
// return num;
//}
//- (NSString *) color
//{
// return color;
//}
//- (void) setNum:(int)_num andColor:(NSString *)_color
//{
// num = _num;
// color = _color;
//}
- (void) print
{
NSLog(@"num: %d, color: %@", num, color);
}
@endBaby.h
#import <Foundation/Foundation.h>
#import "Toy.h"
@interface Baby : NSObject
@property (nonatomic, retain) Toy * toy;
@property (nonatomic, retain) NSString * name;
@property (nonatomic) int age;
//- (Toy *) toy;
//- (NSString *) name;
//- (int) age;
//- (void) setToy:(Toy *)_toy;
//- (void) setName:(NSString *)_name andAge:(int)_age;
- (void) print; //不声明只实现,就是私有方法,只能在.m中使用
//- (void) dealloc; //系统自动调用,就算不声明只实现,也可以正常使用
@end
////assign
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// toy = _toy;
//}
////retain
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}
////copy
//get
//- (Toy *) toy;
//- (Toy *) toy
//{
// return toy;
//}
//set
//- (void) setToy:(Toy *)_toy;
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}Baby.m
#import "Baby.h"
@implementation Baby
@synthesize name, age, toy;
//- (Toy *) toy
//{
// return toy;
//}
//- (NSString *) name
//{
// return name;
//}
//- (int) age
//{
// return age;
//}
//- (void) setToy:(Toy *)_toy
//{
// if (toy != _toy)
// {
// [toy release];
// toy = [_toy retain];
// }
//}
//- (void) setName:(NSString *)_name andAge:(int)_age
//{
// name = _name;
// age = _age;
//}
- (void) print
{
NSLog(@"name: %@, age: %d", name, age);
[toy print];
}
- (void) dealloc
{
[toy release];
[super dealloc];
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Baby.h"
int main()
{
@autoreleasepool
{
Baby * b = [[Baby alloc] init]; //初始化的Baby含有指针toy,但为nil,因为没有新建Toy对象并赋值
b.name = @"AAA";
b.age = 5;
b.toy.color = @"紫";
b.toy.num = 5;
[b print];
NSLog(@"num: %d, color: %@", b.toy.num, b.toy.color);
Toy * t1 = [[Toy alloc] init];
t1.num = 10;
t1.color = @"红";
[t1 print];
Toy * t2 = [[Toy alloc] init];
t2.num = 20;
t2.color = @"绿";
[t2 print];
b.toy = t1;
[b print];
b.toy = t2;
[b print];
b.toy.color = @"紫";
b.toy.num = 5;
NSLog(@"num: %d, color: %@", b.toy.num, b.toy.color);
[b release];
[t1 release];
[t2 release];
}
}
B、组合
XYPoint.h
#import <Foundation/Foundation.h>
@class Circle;
@interface XYPoint : NSObject
{
int x;
int y;
}
@property int x, y;
- (void) setX:(int)xVal andY:(int)yVal;
@endXYPoint.m
#import "XYPoint.h"
@implementation XYPoint
@synthesize x, y;
- (void) setX:(int)xVal andY:(int)yVal
{
x = xVal;
y = yVal;
}
@endCircle.h
#import <Foundation/Foundation.h>
//#import "XYPoint.h"
@class XYPoint;
@interface Circle : NSObject
4000
{
int radius;
XYPoint * origin;
}
@property int radius;
- (XYPoint *) origin;
- (void) setOrigin : (XYPoint *)pt;
- (int) area;
- (int) perimeter;
@end
//objective-c中,当一个类使用到另一个类时,并且在类的头文件中需要创建被引用的指针时,如下面代码:
//A.h文件
//#import "B.h"
//@interface A : NSObject {
// B *b;
//}
//@end
//为了简单起见:A类是引用类,B类是被引用类,这里先不考虑A类的实现文件。
//通常引用一个类有两种办法:一种是通过#import方式引入;另一种是通过@class引入;
//这两种的方式的区别在于:
//1、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法;@class方式只是告诉编译器在A.h文件中 B *b 只是类的声明,具体这个类里有什么信息,这里不需要知道,等实现文件中真正要用到时,才会真正去查看B类中信息;
//2、使用@class方式由于只需要被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所以需要使用#importl来包含被引用类的头文件;
//3、通过上面2点也很容易知道在编译效率上,如果有上百个头文件都#import了同一 个文件,或者这些文件依次被#improt(A->B, B->C,C->D…),一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的,而相对来讲,使用@class方式就不会出现这种问题了;
//4、对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,B类的代码:
//#import "A.h"
//@interface B : NSObject {
// A *a;
//}
//@end
//当程序运行时,编译会报错,
//当使用@class在两个类相互声明,就不会出现编译报错。
//由上可知,@class是放在interface中的,只是在引用一个类,将这个被引用类作为一个类型,在实现文件中,如果需要引用到被引用类的实体变量或者方法时,还需要使用#import方式引入被引用类。Circlr.m
#import "Circle.h"
#import "XYPoint.h"
@implementation Circle
@synthesize radius;
- (XYPoint *) origin
{
return origin;
}
- (void) setOrigin : (XYPoint *)pt
{
origin = pt;
}
- (int) area
{
return 3.14 * radius * radius;
}
- (int) perimeter
{
return 2 * 3.14 * radius;
}
@endmain.m
#import <Foundation/Foundation.h>
#import "Circle.h"
#import "XYPoint.h" //如果不包含会报错,XYPoint是外部定义的类
int main()
{
@autoreleasepool
{
XYPoint * p = [[XYPoint alloc] init];
p.x = 2;
p.y = 2;
Circle * c = [[Circle alloc] init];
c.radius = 2;
NSLog(@"%d",c.radius);
c.origin = p;
NSLog(@"%@",c.origin);
NSLog(@"%d, %d",c.origin.x, c.origin.y);
NSLog(@"%d, %d",[[c origin] x], [[c origin] y]);
}
return 0;
}
相关文章推荐
- ObjC第一节:OC类、消息
- ObjC第七节:文件操作
- ObjC第六节:(2)OC常用类
- ObjC第六节:OC常用类
- ObjC第五节:(2)代理(委托)
- ObjC第五节:协议和分类
- ObjC第四节:继承
- ObjC第三节:内存管理
- nginx启动,重启,关闭命令;以及升级nginx切换命令
- Mahout推荐系统引擎RecommenderEvaluator源码解析
- HDOJ--1102--Constructing Roads(包含题意)
- 窗口与视图UIScreen and UIView
- 2015 Multi-University Training Contest 7 hdu 5373 The shortest problem
- LNMP—Nginx的域名跳转
- JAVA基础一大堆0811数据库
- 教你彻底学会动态规划——进阶篇
- iOS开发之OC类和对象
- [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第十三章 协议
- 数据结构实验之链表五:单链表的拆分
- 剪枝理论