第一、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自動釋放池解析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
__weak修飾符詳解
第一、weak弱引用不能持有對象實例。 在持有某對象的弱引用時,若該對象被廢棄,則此弱引用自動失效並處於nil被賦值的狀態。 第二、實例 id __weak obj1=nil; { /*
richard_如风
2020-06-24 03:50:58
__bridge_retained/__bridge_transfer/__bridge使用詳解
richard_如风
2020-02-25 09:14:51
KVC方法詳解與實現原理
richard_如风
2020-02-25 09:14:51
__weak修飾符詳解
第一、weak弱引用不能持有對象實例。 在持有某對象的弱引用時,若該對象被廢棄,則此弱引用自動失效並處於nil被賦值的狀態。 第二、實例 id __weak obj1=nil; { /*
richard_如风
2020-06-24 03:50:58
objective C中繼承、協議、分類和多態的實現
richard_如风
2020-02-25 09:14:51
__bridge_retained/__bridge_transfer/__bridge使用詳解
richard_如风
2020-02-25 09:14:51
KVC方法詳解與實現原理
richard_如风
2020-02-25 09:14:51
ARC使用規則
richard_如风
2020-02-25 09:14:51
二叉樹相關算法實現-iOS
AgrueLong
2018-08-30 22:27:28
MAC開發之NSTableView
AgrueLong
2018-08-30 22:27:28
Cocoa之Core Data 框架詳解
AgrueLong
2018-08-30 22:27:27
CALayer 基本基礎
FabricMilk
2018-08-24 21:11:27
Objective-C Runtime
FabricMilk
2018-08-24 21:11:27
strong,weak小記
FabricMilk
2018-08-24 21:11:27
Block
FabricMilk
2018-08-24 21:11:27