点语法的内存管理
1)赋值
assign:直接赋值,默认 只是一个别名
retain:保留的这个对象,两个对象指向了同一个位置。
copy:拷贝对象
开辟了一个新的内存空间,分别指向了不同的内存位置,引用技术分别为1,与之前的对象完全脱离了关系。这里我们尤其需要注意,某些时候Copy的作用相当于retain,我们将在复制对象再一次讨论这个问题。
* 使用assign: 对基础数据类型 (NSInteger)和C数据类型(int, float, double, char,等
* 使用copy: 对NSString
* 使用retain: 对其他NSObject和其子类
2)读写性
readwrite:生成getter、setter方法,默认
readonly:生成getter方法
3)原子性
atomic:多线程环境下,存在线程保护,默认
nonatomic:多线程环境下,不存在线程保护
自动释放池
自动释放池基本概念:
NSAutoreleasePool*pool = [[NSAutoreleasePool alloc]init];(老版本5.0以前)
@autoreleasepool { } (新版本 5.0以后)
凡是被添加到自动释放池的对象都会在[pool drain];时对其中的每个对象发送一条release消息
注意:在处理Foundation程序时,为了使用其中对象,必须设置自动池。系统使用这个池跟踪对象,以便以后释放。
自动回收池并未包含对象本身,而是关于对象的引用
由new、copy、alloc创建的对象不会自动入池,需发送release消息释放内存
或通过发送autorelease消息,可以将一个对象添加到其中,以便以后释放:[myFraction autorelease];
注意:
程序中可以有多个自动释放池,并且它们可以是嵌套的
Eg:
NSAutoreleasePool *tempPool;
...
for (i = 0; i<n; ++i) {
tempPool = [[NSAutoReleasePool alloc] init];
... // lots of work with temporary objects here
[tempPool drain];
}
内存泄露
为了防止内存泄露。无论什么时候,我们创建一个对象,或者创建一个对象的拷贝,我们都必须通过release方法释放。
Eg:
-(void) myMethod {
NSString * myString = [[NSString alloc] init]; //retainCount=1
Foo * myFoo = [[Foo alloc] initWithName:myString]; //retainCount=1
NSLog("Foo's Name:%@", [myFoo getName]);
[myFoo release]; //retainCount=0 so deallocate
[myString release]; //retainCount=0 so deallocate
}
对象所有权
概念
任何对象都可能拥有一个或多个所有者。只要一个对象至少还拥有一个所有者,它就会继续存在
Cocoa所有权策略
任何自己创建的对象都归自己所有
可以使用名字以“alloc”或“new”开头或名字中包含“copy”的方法创建对象
可以使用retain来获得一个对象的所有权
引用计数
标识对象当前被引用的次数。如果一个对象同时在三个地方被引用(如存放在数组中等),其引用计数值应该为3
只有当前对象引用计数为0时,也就是没有人再使用该对象后,才能释放它占用的内存
每个对象创建时引用计数自动设置为1。再有其他对象引用时,通过发送retain消息使该对象的引用次数加1 [myFraction retain];
不再需要对象时,可以通过发送release消息,使对象引用次数减1 [myFraction release];
要成功的运用引用计数必须足够的细心,以保证再程序运行期间正确地增减对象的引用次数
系统会自动处理一些对象的引用次数,但并不是对所有对象都如此向对象发送retainCount消息可以获得当前对象的引用计数,它返回一个NSUInterger类型的无符号整数
Eg:
#import <Foundation/NSObject.h>
int main (intargc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSNumber *myInt = [NSNumber numberWithInt: 100];
NSNumber *myInt2;
NSMutableArray *myArr = [NSMutableArray array];
NSLog (@"myInt retain count = %i", (int) [myInt retainCount]); //1
[myArr addObject:myInt];
NSLog (@"after adding to array = %i", (int) [myInt retainCount]); //2
myInt2 = myInt;
NSLog (@"after asssignment to myInt2 = %i",
(int) [myInt retainCount]); //2
[myInt retain];
NSLog (@"myInt after retain = %i", (int) [myInt retainCount]); //3
NSLog (@"myInt2 after retain = %i", (int) [myInt2 retainCount]); //3
[myInt release];
NSLog (@"after release = %i", (int) [myInt retainCount]); //2
[myArr removeObjectAtIndex: 0];
NSLog(@"after remove from array = %i ", (int) [myIntretainCount]); //1
[pool drain];
return 0;
}
三种获得对象所有权的方式
1)
-(void) setStr: (NSMutableString *) s
{
if( str != s)
{
[str release];
str = s;
[s retain];
}
}
2)
-(void) setStr: (NSMutableString *) s
{
[str autorelease];
str = [s retain];
}
3)
-(void) setStr: (NSMutableString *) s
{
[s retain];
[str release];
str = s;
}