import <Foundation/Foundation.h>
import "Person.h"
int main(int argc, const char * argv[]) {
Person *per = [[Person alloc] init];
per.name = @"xiaolaohu";
NSLog(@"retainCount: %lu", per.retainCount);
[per retain];
NSLog(@"retainCount: %lu", per.retainCount);
[per retain];
NSLog(@"retainCount: %lu", per.retainCount);
Person *per1 = per;
NSLog(@"retainCount: %lu", per1.retainCount);
[per release];
NSLog(@"retainCount: %lu", per1.retainCount);
[per release];
NSLog(@"retainCount: %lu", per1.retainCount);
// 當引用計數(shù)為1時, 在release系統(tǒng)會認為此事應該銷毀對象, 所以引用計數(shù)從1到0的減法運算實際并沒有做
[per release];
NSLog(@"retainCount: %lu", per1.retainCount);
// // 當對象銷毀時再次發(fā)送release消息, 就會發(fā)生內(nèi)存過度釋放
// [per release];
// 有時候crash, 有時候不crash, 因為我們最后一次release相當于告訴系統(tǒng)這塊內(nèi)存不再使用, 可以重新分配, 如果此內(nèi)存被重新分配, 就會crash, 沒有分配就不會crash
// NSLog(@"name: %@", per.name);
// 安全釋放: 為了防止野指針, 我們使用完之后給指針置為nil
per = nil;
[per sayHi];
/**
* 內(nèi)存管理原則
* 1. 凡是使了alloc、retain 或者copy讓內(nèi)存的引用計數(shù)增加了,就需要使release或 者autorelease讓內(nèi)存的引用計數(shù)減少势似。在一段代碼內(nèi),增加和減少的次數(shù)要相等叙甸。
* 2. 如果增加的次數(shù)大于減少的次數(shù),會造成內(nèi)存泄露葬毫。
* 3. 如果增加次數(shù)小于減少的次數(shù),會造成過度釋放匾嘱。
* 4. 如果增加的次數(shù)等于減少的次數(shù),還繼續(xù)訪問,造成野指針問題氮趋。
*/
Person *p3 = [[Person alloc] init];
[p3 retain];
[p3 retain];
NSLog(@"p3: %lu", p3.retainCount);
@autoreleasepool {
NSLog(@"p3: %lu", p3.retainCount);
}
// 把一個對象添加到一個集合中會對該對象的引用計數(shù)加1, 如果移除會對該對象的引用計數(shù)減1
Person *p4 = [[Person alloc] init];
NSMutableArray *arr = [NSMutableArray array];
[arr addObject:p4];
[p4 release];
// 字符串直接賦值實質(zhì)上是賦了一個常量字符串, 不要嘗試release一個常量, 因為沒有用
NSString *str = @"wsz"; // -1
[str release];
[str release];
NSLog(@"str: %ld", str.retainCount);
NSString *str0 = @"嘿嘿嘿"; // -1
NSLog(@"str0: %ld", str0.retainCount);
NSString *str1 = [[NSString alloc] init]; // -1
NSLog(@"str1: %ld", str1.retainCount);
NSString *str2 = [NSString string]; // -1
NSLog(@"str2: %ld", str2.retainCount);
NSString *str3 = [[NSString alloc] initWithFormat:@"aaa"]; // -1
NSLog(@"str3: %ld", str3.retainCount);
NSString *str4 = [[NSString alloc] initWithFormat:@"哈哈哈"]; // 1
NSLog(@"str4: %ld", str4.retainCount);
NSString *str5 = [NSString stringWithFormat:@"wer"]; // -1
NSLog(@"str5: %ld", str5.retainCount);
NSString *str6 = [NSString stringWithFormat:@"啊啊啊"]; // 1
NSLog(@"str6: %ld", str6.retainCount);
Person *p5 = [[Person alloc] init];
p5.name = @"king old luck";
Person *p6 = [p5 copy];
NSLog(@"p5: %p, p6: %p", p5, p6);
// 不可變字符串調(diào)用copy方法, 是淺拷貝, 拷貝的是指針
// 不可變字符串調(diào)用mutableCopy方法, 是深拷貝, 拷貝的是內(nèi)容, 拷貝后得到的副本為可變字符串
NSString *string = @"tyu";
NSMutableString *mutableString = [string mutableCopy];
[mutableString appendString:@"aaa"];
NSLog(@"mutable: %@", mutableString);
// 可變字符串使用copy方法是深拷貝, 得到的是不可變副本
// 可變字符串使用mutableCopy是深拷貝, 得到的是可變副本
NSMutableString *mStr = [NSMutableString stringWithFormat:@"aaaa"];
NSString *mStr1 = [mStr copy];
NSLog(@"mutable: %@", mStr1);
return 0;
}