您的位置:首页 > 运维架构

@property,autorelease 知识点总结

2015-12-08 15:51 453 查看
1 @property 参数(二)
// 重点掌握
A.是否要生成set方法( 若为只读属性,则不生成)
readonly:只读,只会生成getter的声明和实现
readwrite:默认的,同时生成setter和getter的声明和实现

2.多线程管理(苹果在一定程度上屏蔽了多线程操作)
nonatomic :高性能,一般使用这个 // 一般使用nonatomic
atomic :低性能,默认

3.set和get方法的名称
修改set和get方法的名称,主要用于布尔类型.因为返回布尔类型的方法名一般以is开头,修改名称一般用在布尔类型中的getter.

@property (nonatomic ,assign,setter=haha:,getter=abc)
int age
可以理解为把[p setAge:haha]---->[p abc:], [p age]->[p haha];

@property (nonatomic ,assign,setter=setVip:,getter=isVip) BOOL vip;
用法:设置值 [ person setVip:YES];获取值 BOOL vip=[person isVip];

1.@class 的使用格式: @class 加类名 : // 重点

含义: 告诉编译器, Dog 是一个类,至于类有哪些属性和方法,并没有检查.
好处:如果Dog文件内容发生了改变,而不需要重新编译.

2.具体使用

在.h 文件中使用@class引用一个类
在.m 文件中使用#import包含这个类的.h文件

#import "B.h"

@interface A :NSObject {


B *b;


}

end

[/code]

为了简单起见: A类是引用类,B类是被引用类,这里先不考虑A类的实现文件.

通常引用一个类有两种方法: 一种是通过#import 方式引入; 另一种是通过@class引入

6.两种方式的区别是什么? // 面试题
1.作用上的区别2.效率上的区别
A.#import方法会包含被引用类的所有信息,包括被引用类的变量和方法

B.使用@class方式由于只需要被引用类(B类)的名称就可以了,而在实现类由于要用到被引用类中的实体变量和方法,所有需要使用#import来包含被引用类的头文件.

C.一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,这样的效率也是可想而知的.

7.对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类



8.循环retain问题
@class Person;

@interface Dog :NSObject

@property(nonatomic,retain) Person *owner;

@end


#import <Foundation/Foundation.h>

@class Dog;

@interface Person :NSObject

@property (nonatomic ,assign) Dog *dog;

@end


Dog *d=[ Dog new];

Person *p=[Person new];

[/code]

循环retain的场景 ,比如A对象retain了B对象,B对象retain了A对象
循环retain的弊端,这样会导致A对象和B对象永远无法释放

循环retain的解决方案
当两端互相引用时,应该一端用retain,一端用assign

9.autorelease是什么?
答:A.在ios程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的. B. 当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中.

10. 为什么会有autorelease?
答:OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放.

11.使用autorelease的好处
a.不需要再关心对象释放的时间b.不需要关心什么时候调用release

12.autorelease基本用法
a. 会将对象放到一个自动释放池中
b. 当自动释放池被销毁时,会对池子里的所有对象做一次release
c.会返回对象本身
d. 调用完autorelease方法后,对象的计数器不受影响(销毁时影响)

13.autorelease 什么时候被释放?
a.手动释放autorelease pool b.run loop 结束后自动释放

#import "Person.h"

int main( ){

// 创建自动释放池

Person *p= [ Person new] ;// p= 1

@autoreleasepool {


[p run];

NSLog(@" %lu",p.retainCount); // 1

//p autorelease ] 把对象p加入到自动释放池中

// 注意:加入到自动释放池中以后,引用计算不会变化



[p autorelease]; // 加入自动释放池


NSLog(@"%lu",p.retainCount); // 1

[p run];

}

return 0;

}

[/code]

14.[掌握] autorelease 使用注意:
a. 并不是放到自动释放池代码中,都会自动加入到自动释放池,因为没有调用 autoreleaase方法.
b. 自动释放池的嵌套使用
c. 自动释放池中不适宜放占用内存比较大的对象

15.autorelease的应用场景:经常用来在类方法中快速创建一个对象.
16.完善快速创建对象的方法: instancetype 可以智能判断返回的类型和接受的类型是否一致.

int main( ){

NSString *str=[NSString stringWithForma:@"xxx"];


NSArray * array =[NSArry array ];

NSDictionary *dic= [NSDictionary dictionary] // 系统数组字典,快速创建方法

Person *p= [Person person];

//1.创建一个对象p

// 2. 用完之后,系统把对象释放掉 p


Person *p =[[ Person alloc] init];

[ p autorelease];

[/code]

17.构造方法特点
初始化 --->构造方法 init
--->自定义构造方法
// new 方法执行两个方法
1.+ alloc :去给对象分配一块内存空间
2. -init :初始化这个对象

// 下面两步操作等效于:[Person new];
// Person *per1= [Person alloc];
// Person *per2 =[per1 init] ;

等效于上面两步,方法的级连调用.
Person *per3=[[Person alloc]init];
per3.age=10;
NSLog(@"%d",Per3.age);
1) 对象
2) 返回值是id或者 instancetype
3) initWithXXX
id 指针的用法: 是一个指针,这个指针的类型是id类型.
作用:可以表示任意的OC对象的指针--万能指针,等效于:NSObject *;
注意: id不用加 *, 其里面已经封装好了,相对于id==NSObject *
访问指向类对象的独有方法时,必须要强转.
id per2=[Person new];
((Person *)per2).name=@"张山";
NSLog(@"%@",((Person *)Per2).name);

#import "Student.h"


@implementation Student

-(void) dealloc

{


 NSLog(@" Student dealloc");// 快速创建

 [super dealloc] ; // 调用父类方法 释放

}


+(instancetype)personWithAge:(int)age{

return [[[ self alloc] initWithAge :age] autorelease];

}

-(instancetype)initWithAge:(int)age{// 自定义一个构造方法


if (self =[super init]){} // 先初始化父类的,并且判断是否初始化成功

[/code]

18. 指针分类

1)强指针 : 默认的情况下,所有的指针都是强指针, 关键字 strong
2) 弱指针: _ _weak 关键字修饰的指针
声明一个弱指针如下: _ _ weak Person *p;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: