一、@property参数
1.参数可有可无。基本类型可以用@property(assign)intage; 直接赋值,写不写一样的。
2.参数主要分三类:1.)读写属性:readwrite /readonly /
2.) setter处理:assign /retain /copy
2.) 原子性:atomicity /nonatomic (加锁会耗性能,尽量使用nonatomic)
3.为了保证代码的可读性,在BOOL类型生成getter尽量重名为isXxx,ex:isRich.
二、示例以下面的程序为示例,来看看@property的参数使用
@class Book;
@class Card;
@interface Student : NSObject
// 这里的retain代表:在set方法中,release旧值,retain新值
@property (nonatomic, retain) Book *book;
@property (retain) Card *card;
// readonly代表只生成get方法的声明
// 默认是readwrite,同时生成get和set方法的声明
@property (readonly) int age;
// atomic就代表给方法进行加锁,保证线程安全
@property (atomic) int no;
// nonatomic代表方法不需要考虑线程安全问题
@property (nonatomic, assign) int no2;
// getter是用来指定get方法的方法名
@property (nonatomic, getter = isRich) BOOL rich;
@end
@implementation Student
//- (void)setBook:(Book *)book {
// if (_book != book) {
// [_book release];
// _book = [book retain];
// }
//}
//
//- (void)setCard:(Card *)card {
// if (_card != card) {
// [_card release];
// _card = [card retain];
// }
//}
- (void)dealloc {
NSLog(@"Student被销毁了");
[_book release];
//self.book = nil;
[_card release];
//self.card = nil;
[super dealloc];
}
@end
在main方法中写个测试如下:
@autoreleasepool {
Student *stu = [[Student alloc] init];
Book *book = [[Book alloc] init];
stu.book = book;
[book release];
Book *book2 = [[Book alloc] init];
stu.book = book2;
[book2 release];
stu.rich = YES;
BOOL rich = stu.isRich;
[stu release];
}
三、自动释放池(autorelease pool)
1.自动释放池是OC里面的一种自动回收机制,一般可以将一些变量添加到自动释放池中统一释放。
当自动释放池销毁时,池里面的所有对象都会调用一次release方法。
2.OC对象只需要发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池)
3.autorelease实际上只是把对release的调用延迟了,对于每一次autorelease,系统只是把该对象放入当前的autorelease pool,当该pool被释放时,该pool中的所有对象都会调用release。
@自动释放池作用:统一回收对象。
@说明:
1.自动释放池被销毁,所有对象计数器减一,并不一定会被销毁。
2.@autoreleasepool { }运行完了就销毁自动释放池。
3.[stu autorelease];不会马上释放,会交给池子管。
4.对于每一个Runloop,系统隐式创建一个AutoRelease pool,并把创建好的pool放在栈顶,所有的pool会构成一个栈式结构。在每一个Runloop结束时,当前栈顶的pool会被销毁,这样这个pool里的每个对象会执行release操作。
@自动释放池创建:
1.iOS 5.0之后
@autoreleasepool {Student *stu = [[[Student alloc] init] autorelease];…}
2.iOS5.0之前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc ] init ] ;[ pool release ] ;
3.静态对象用以快速创建对象。
4.ios开发潜规则:静态方法返回对象都是自动释放的。
@自动释放池注意:
1.在ARC下,不能使用 [[NSAutoreleasePool alloc ] init ] ,而应当使用@autoreleasepool{}
2.不要把大量循环操作放在同一个自动释放池中,这样会造成内存峰值上升。
3.尽量避免对大内存使用该方法,对于这种延迟释放机制,还是尽量少用。
4.SDK中一般利用静态方法创建并返回的对象都是已经autorelease的,不需要再进行release操作。
四、示例
int main(int argc, const char * argv[])
{
// @autoreleasepool代表创建一个自动释放池
@autoreleasepool {
Student *stu = [[[Student alloc] init] autorelease];
//[stu autorelease];
Student *stu1 = [[[Student alloc] init] autorelease];
//[stu1 autorelease];
// 这个stu2是自动释放的,不需要释放
Student *stu2 = [Student student];
// 这个str是自动释放的,不需要释放
NSString *str = [NSString stringWithFormat:@"age is %i", 10];
for (int i = 0; i<1000; i++) {
[Student student];
}// 尽量不要这样,不会及时释放,还会造成峰值高
}
return 0;
}