首页 > 代码库 > Foundation框架常用数据类型和NSAutoreleasePool自动释放池解析

Foundation框架常用数据类型和NSAutoreleasePool自动释放池解析

第一、NSAutoreleasePool自动释放池解析


1、自动释放池的物理实现


自动释放池用栈来实现,当你创建一个新的自动释放池是,会压栈到栈顶,接受autorelease消息的对象也会被压入到栈顶
NSAutoreleasePool实现延时释放,内部包含一个数组(NSMutableArray),用来保存声名为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数 组,release数组中的每个成员,如果release之后,retain count大于0,此对象依然没有被销毁,内存泄露。
2、当我们使用copy、alloc、retain得到一个对象时,必须调用release或者是autorelease进行释放,其他方法获得对象将由自动释放池释放


3、release和drain的区别


当我们向自动调用【pool release 】时,池内元素都会调用release方法,并且池释放掉,但是当我们调用drain方法时,只会执行前者


4、自动释放池的销毁时间


当我们使用appkit创建工程时,程序会自动创建或排空自动释放池的对象,通常实在一个时间循环中创建,在结束时排空


5、自动释放池的作用域与嵌套
AutoreleasePool是可以嵌套使用的,池是被嵌套的,嵌套的结果是个栈,同一线程只有当前栈顶pool实例是可用的:
 当短生命周期内,比如一个循环中,会产生大量的临时内存,可以创建一个临时的autorelease pool,这样可以达到快速回收内存的目的;
 NSAutoreleasePool *pool;
    pool=[[NSAutoreleasePool alloc] init];
    {
        for (int i=0; i<100000; i++)
        {
            NSObject *obj=[[[NSObject alloc] init] autorelease];
            NSLog(@"the obj is%@",obj);


            if(i%10000==0)
            {
                [pool drain];
                pool=[[NSAutoreleasePool alloc] init];


            }
        }
    }
    [pool drain];


6、自动释放池带来的问题
Cocoa应用程序中的每个线程都会维护一个自己的NSAutoreleasePool对象的堆栈。当一个线程终止时,它会自动地释放所有与自身相关的自动释放池。在基于Application Kit的应用程序中,自动释放池会在程序的主线程中被自动创建和销毁。
● 如果你正在编写一个不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持;你必须自己创建它们。
● 如果你生成了一个从属线程,则一旦该线程开始执行,你必须立即创建你自己的自动释放池;否则,你将会泄漏对象。
● 如果你编写了一个循环,其中创建了许多临时对象,你可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些对象。这可以帮助减少应用程序的最大内存占用量
 第四、IOS内存管理的三句话
谁创建,谁释放:
解释:通过alloc、new、copy创建的对象,必须调用release、autorelease释放
谁retain,谁释放
retain的次数和release、autorelease次数相同
没创建且没有retain,别释放


第二、Foundation FrameWork


定义了多种与基本数据类型类型对应的类,如NSNumber,NSInteger,NSString等,所有从NSSobject继承创建都是对象


NSArray/NSMutalbeArray, NSDictionary/NSDictionary 包含的对象只能是对象,不能使基本数据类型,应采用NSNumber


mutable表示内容可变,非mubable
NSString和NSMutableString


int main(int argc, const char * argv[])
{
    //NSArray *colors=[NSArray arrayWithObjects:@"hello",@"richard",@"yang", nil];
    NSString *str=[NSString stringWithFormat:@"hello,richard,yang"];
    NSArray *arr=[str componentsSeparatedByString:@","];
    NSLog(@"retaincount is% ld",[str retainCount]);
    for(int i=0;i<arr.count;i++)
    {
        NSLog(@"The element is %s",[[arr objectAtIndex:i] UTF8String]);
    }
    NSNumber *myNum=[NSNumber numberWithInt:3];
    NSLog(@"the val is %@",myNum);
    
    NSMutableArray *array=[[NSMutableArray alloc] initWithCapacity:4];
    [array addObject:@"hello"];
    [array insertObject:@"what " atIndex:1];
    NSLog(@"THE LAST IS %@",[array lastObject]);
    return 0;
}


关于上述代码的几点说明:
1.用类方法创建的对象,不需要release,会自动释放,用实例方法创建的对象需要release


2.NSArray和NSDictionary可以放各种类型的对象,但不能放基本类型


3.调用函数返回值是对象类型,不需要考虑内存释放的问题,一般情况下这种返回值会autorelease,遵循谁创建谁释放的原则


第三、NSDictionary 和 NSMutableDictionary 常用方法详解
dictionaryWithObjectsAndKeys 用来初始化
objectForKey 用来取值
sample:
NSDictionary *testDic=[NSDictionary dictionaryWithObjectsAndKeys:@"1",@"hello",@"2",@"what", nil];
    NSLog(@"val is %@",[testDic objectForKey:@"hello"]);
NSMutableDictionary可变字典NSMutableDictionary继承自NSDictionary


常用api:
dictionaryWithCapacity: 用来初始化
setObject: 设置
removeObjectForKey 删除
[count] 返回字典的数量
[allKeys]获取所有键的集合
[allValues】获取所有值得集合
sample:
NSMutableDictionary *testDic=[NSMutableDictionary dictionaryWithCapacity:12];
        [testDic setObject:@"1" forKey:@"hel"];
        [testDic setObject:@"2da" forKey:@"what"];
        [testDic setObject:@"hello" forKey:@"hello"];
        NSLog(@"the val is %@",[testDic objectForKey:@"what"]);
        NSLog(@"the length is %ld",[testDic count]);
        [testDic removeObjectForKey:@"hello"];
        NSLog(@"the length is %lu",testDic.count);
        
        NSArray *keyArray=[testDic allKeys];
        NSArray *valArray=[testDic allValues];
        NSLog(@"the all keys are %@",keyArray);
        NSLog(@"the all values are %@",valArray);
    }


</span>


返回结果是:
2013-10-09 17:20:19.533 element[401:303] the val is 2da
2013-10-09 17:20:19.535 element[401:303] the length is 3
2013-10-09 17:20:19.536 element[401:303] the length is 2
2013-10-09 17:20:19.537 element[401:303] the all keys are (
    what,
    hel
)
2013-10-09 17:20:19.537 element[401:303] the all values are (
    2da,
    1
)
不经常用的方法为
- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
- (void)removeAllObjects;
- (void)removeObjectsForKeys:(NSArray *)keyArray;
- (void)setDictionary:(NSDictionary *)otherDictionary;
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)keyNS_AVAILABLE(10_8,6_0);
sample如下:
NSMutableDictionary *emptyDic=[NSMutableDictionary dictionary];
        [emptyDic setValue:@"2" forKey:@"2"];
        NSLog(@"empty DIC is %@",emptyDic);
        NSMutableDictionary *testDic=[NSMutableDictionary dictionaryWithObjectsAndKeys:@"hello",@"1",@"andy",@"2",@"yang",@"3",nil];
        
        NSDictionary *dic4=[NSDictionary dictionaryWithObject:@"yang" forKey:@"4"];
        [testDic addEntriesFromDictionary:dic4];
        NSLog(@"the mutalble dictionary is %@",testDic);
        [emptyDic setDictionary:testDic];
        NSLog(@"empty DIC is %@",emptyDic);
        
        NSArray *deleteArr=[NSArray arrayWithObjects:@"1",@"2",@"yang",nil];
        [testDic removeObjectsForKeys:deleteArr];
        NSLog(@"the mutalble dictionary is %@",testDic);
        
        [testDic removeAllObjects];
        NSLog(@"the mutalble dictionary is %@",testDic);




结果:
2013-10-09 17:39:37.832 element[463:303] empty DIC is {
    2 = 2;
}
2013-10-09 17:39:37.834 element[463:303] the mutalble dictionary is {
    1 = hello;
    2 = andy;
    3 = yang;
    4 = yang;
}
2013-10-09 17:39:37.834 element[463:303] empty DIC is {
    1 = hello;
    2 = andy;
    3 = yang;
    4 = yang;
}
2013-10-09 17:39:37.835 element[463:303] the mutalble dictionary is {
    3 = yang;
    4 = yang;
}
2013-10-09 17:39:37.835 element[463:303] the mutalble dictionary is {
}


遍历字典的方法:
for(id key in dic)
{
 id obj=[dic objectForKey:key];
NSLog(@"%@",obj);
}
一般的枚举
        NSMutableDictionary *testDic=[NSMutableDictionarydictionaryWithObjectsAndKeys:@"hello",@"1",@"andy",@"2",@"yang",@"3",nil];
        for(int index=0;index<[testDiccount];index++)
        {
            NSString *obj=[testDic objectForKey:[[testDic allKeys] objectAtIndex:index]];
            NSLog(@"the val is %@",obj);
        }
        
        for(id key in testDic)
        {
            NSString *obj2=[testDic objectForKey:key];
            NSLog(@"the val is %@",obj2);
        }
第四、NSString 和NSMutableString 使用技巧
1、字符串的创建
创建简单字符串
NSString *string=@"hello";
创建空字符串
NSString *str2=[[NSStringalloc] init];
NSString *str3=[NSString string];
创建格式化字符串 
NSString *str5=[NSString stringWithFormat:@"hello %d",34]; //是在堆创建的
当用“==”来判断两个字符串时,实际上是判断地址是否相同
下面三个初始化语句的都是在常量区创建的
NSString *string1=@"hello";
NSString *string2=[NSString stringWithString:@"hello"];
NSString *string1=[[NSString alloc] initWithString:@"hello"];
if (string1==string2) {
NSLog(@"they are same");
}
/**
* 字符串的格式化stringWithFormat 
*/
NSString *str=[NSString stringWithFormat:@"我%d",7];
NSLog(@"str:%@",str);
/*
*length supoort chinese
*/
unsigned int lengh=(unsigned int)[str length];
NSLog(@"length:%d",lengh);
/*
*定义个string对象,最好初始化,
*/
NSString *str2=@"我7";


stringwithcapacity 用来初始化NSMutableString


2、字符串的比较
compare、isEqualToString :用来做比较
if([str isEqualToString:str2])
{
NSLog(@"They are the same");
}
/*
* 不区分大小写 compare options
*/
NSString *str3=@"Block";
NSString *str4=@"block";
if([str3 compare:str4 options:NSCaseInsensitiveSearch]==0)
{
NSLog(@"insensitive same");
}




3、字符串和float、int型的转换
[str floatValue] 转换为float型,[str invValue] 转换为整型 
componentsSeparatedByString实现将字符串分割为数组
NSString *test=[NSString stringWithFormat:@"3.14"];
float f=[test floatValue];
NSLog(@"float val is %.2f",f);


int i=[test intValue];
NSLog(@"the int val is %i",i);


NSString *str=[NSString stringWithFormat:@"one two three"];
NSArray *arr=[str componentsSeparatedByString:@" "];
NSLog(@"the arr is %@",arr);




4、截取字符串


substringFromIndex、
substringToIndex、
substringWithRange
NSString *str=[NSString stringWithFormat:@"onetwothree"];
NSString *substr=[str substringFromIndex:2];
NSString *substr2=[str substringToIndex:3];
NSLog(@"the arr is %@",substr);
NSLog(@"the arr is %@",substr2);
NSRange range;
range.length=4;
range.location=2;
NSString *substr3=[str substringWithRange:range];
NSLog(@"the arr is %@",substr3);


5、判断是否有前缀
hasprefix. hasSuffix: 用来判断是否有前后缀
NSString *str5=@"draft-hello.mov";
NSString *str6=@"draft";
NSString *str7=@"mov";
if([str5 hasPrefix:str6])
{
NSLog(@"str5 has prefix str6");
}
if([str5 hasSuffix:str7])
{
NSLog(@"str5 has suffix str7");
}


6、字符串的拼接
appendString,appendFormat 用来实现追加
*appendString 和 appendFormat实现追加
*/
[mulstr appendString:@"hello"];
NSLog(@"%@",mulstr);
[mulstr appendFormat:@"hello %d",12];
NSLog(@"%@",mulstr);


NSString *str=[NSString stringWithFormat:@"onetwothree"];
NSString *substr2=[str substringToIndex:3];
NSString *substr3=[substr2 stringByAppendingString:@"hello"];
NSLog(@"the arr is %@",substr3);






7、deleteCharactersInRange 实现删除
/*
* deleteCharactersInRange 执行删除操作
*/
NSRange jackRange;
jackRange=[mulstr rangeOfString:@"ello"];
//jackRange.length++;
[mulstr deleteCharactersInRange:jackRange];
NSLog(@"mulstr:%@",mulstr);


- (void)deleteCharactersInRange:(NSRange)range; 删除字符串
        NSMutableString *str1=[NSMutableString stringWithFormat:
        @"hello what is your name?"];
        NSRange range;
        range=[str1 rangeOfString:@"what"];
        NSLog(@"start is %lu,length is %lu",range.location,range.length);
        [str1 deleteCharactersInRange:range];
        NSLog(@"str is %@",str1);




8、字符串的查询
rangeOfString 用来做查询
typedef struct _NSRange {
     NSUInteger location;  //开始位置
    NSUInteger length;  //长度
} NSRange;
NSRange的定义:
        NSRange range2;
        range2.location = 17;
        range2.length = 4;
        NSLog(@"%lu and  %lu",range2.location,range2.length);
        //用NSMakeRange来初始化
        NSRange rang1=NSMakeRange(12, 23);
        NSLog(@" %lu and %lu",rang1.location,rang1.length);


NSString *str=[NSString stringWithFormat:@"onetwothree"];
NSRange range=[str rangeOfString:@"two"];
if(range.location!=NSNotFound)
{
NSLog(@"the arr is %@",str);
}else
{
NSLog(@"hello");
}




9、NSMutableString 实现字符串的插入
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
- (void)deleteCharactersInRange:(NSRange)range;


10、改变大小写


NSString *myString=@"hello WOrld";
NSLog(@"the upper string is %@",[myString uppercaseString]);
NSLog(@"the lower string is %@",[myString lowercaseString]);
NSLog(@"the cap string is %@",[myString capitalizedString]);


第五、NSArray和NSMutableArray的详解
NSArray有两个限制,首先,只能存储objective c的对象,不能存储c语言的基本语言类型,第二,不能包含nil对象
NSArray的用法:
1、初始化
NSArray *firstArray=[[NSArray alloc] initWithObjects:@"one",@"two",@"three", nil];
        NSArray *secondArray=[NSArray arrayWithArray:firstArray];


2、获取元素个数和访问
        NSLog(@"the number is %ld",[secondArray count]);
        NSLog(@"the value is %@",[secondArray objectAtIndex:2]);


3、追加数据元素
        NSArray *thirdArray=[firstArray arrayByAddingObjectsFromArray:secondArray];


4、数组转化为字符串
        NSString *str=[firstArray componentsJoinedByString:@".."];
        NSLog(@"the number is %@",str);


5、判断是否包含字符串
        NSArray *firstArray=[[NSArray alloc] initWithObjects:@"one",@"two",@"three", nil];
        NSLog(@"has value %d",[firstArray containsObject:@"two"]);
        NSLog(@"has value %ld",[firstArray indexOfObject:@"two"]);
        NSLog(@"the last object is %@",[firstArray lastObject]);


NSMutalbeArray 的用法-
NSMutableArray是可变的,NSArray是不可变的


6、基本的增删改
     NSMutableArray *mutableArr=[NSMutableArray arrayWithCapacity:4];
        [mutableArr addObject:@"hello"];
        [mutableArr addObject:@"hello"];
        [mutableArr addObject:@"hello"];


        [mutableArr addObject:@"richard"];
        [mutableArr insertObject:@"yang" atIndex:1];
        NSLog(@"%@",mutableArr);
        [mutableArr removeObject:@"hello"];
        [mutableArr removeObjectAtIndex:0];
        [mutableArr removeLastObject];
        NSLog(@"%@",mutableArr);


7、替换操作
        [mutableArr replaceObjectAtIndex:0 withObject:@"kaixin"];


8、遍历
        NSMutableArray *mutableArr=[NSMutableArray arrayWithCapacity:4];
        [mutableArr addObject:@"hello"];
        [mutableArr addObject:@"hello"];
        [mutableArr addObject:@"hello"];
        for(int index=0;index<[mutableArr count];index++)
        {
            NSLog(@"the val is %@",[mutableArr objectAtIndex:index]);
        }
        for(NSString *str in mutableArr)
        {
            NSLog(@"%@",str);
        }
        for (id str in mutableArr) {
            NSLog(@"%@",str);
        }
第五、NSNumber的使用
基本数据类型无法用于字典、集合和数组,为此,我们需要将基本数据类型封装成数字对象,在OC中提供了NSNumber解决此问题
1、NSNumber封装的代码:
        int age=12;
        NSNumber *num1=[NSNumber numberWithInt:age];
        NSNumber *num2=[NSNumber numberWithFloat:10.8];
        NSLog(@"the val is %@",num1);
        NSLog(@"the val is %@",num2);
        NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:num1,@"age",num2,@"info", nil];
        // insert code here...
        NSLog(@"%@",dic);
        NSLog(@"Hello, World!");


结果为:
2013-10-08 17:50:58.777 element[1731:303] the val is 12
2013-10-08 17:50:58.779 element[1731:303] the val is 10.8
2013-10-08 17:50:58.779 element[1731:303] {
    age = 12;
    info = "10.8";
}
2013-10-08 17:50:58.780 element[1731:303] Hello, World!




2、NSNumber解析的代码:
        int age=12;
        NSNumber *num1=[NSNumber numberWithInt:age];
        NSNumber *num2=[NSNumber numberWithFloat:10.8];
        NSLog(@"the num is %d",[num1 intValue]);
        NSLog(@"the num is %d",[num2 intValue]);
    }


 创建和初始化类的方法  初始化实例方法     检索实例方法
 numberWithChar:     initWithChar:   charValue
 numberWithUnsignedChar:     initWithUnsignedChar:   unsignedCharValue
 numberWithShort:    initWithShort:  shortValue
 numberWithUnsignedShort:    initWithUnsignedShort:  unsignedShortValue
 numberWithInteger:  initWithInteger:    integerValue
 numberWithUnsignedInteger:  initWithUnsignedInteger:    unsignedIntegerValue
 numberWithInt:  initWithInt:    intValueunsigned
 numberWithUnsignedInt:  initWithUnsignedInt:    unsignedIntValue
 numberWithLong:     initWithLong:   longValue
 numberWithUnsignedLong:     initWithUnsignedLong:   unsignedLongValue
 numberWithLongLong:     initWithLongLong:   longlongValue
 numberWithUnsignedLongLong:     initWithUnsignedLongLong:   unsignedLongLongValue
 numberWithFloat:    initWithFloat:  floatValue
 numberWithDouble:   initWithDouble:     doubleValue
 numberWithBool:     initWithBool:   boolValue

























Foundation框架常用数据类型和NSAutoreleasePool自动释放池解析