object-c java_Object-c 学习入门教程(经典推荐)

當你想用 NSString 或其他 Foundation framework classes 來做更多程式設計工作時,你需要一個更有彈性的系統,也就是使用 Autorelease pools。

當開發 Mac Cocoa 應用程式時,autorelease pool 會自動地幫你設定好。

基於 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一書中的範例,並經過允許而刊載。

main.m #import #import #import int main( int argc, const char *argv[] ) {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *str1 = @"constant string";

NSString *str2 = [NSString stringWithString: @"string managed by the pool"];

NSString *str3 = [[NSString alloc] initWithString: @"self managed string"];

// print the strings

printf( "%s retain count: %x\n", [str1 cString], [str1 retainCount] );

printf( "%s retain count: %x\n", [str2 cString], [str2 retainCount] );

printf( "%s retain count: %x\n", [str3 cString], [str3 retainCount] );

// free memory

[str3 release];

// free pool

[pool release];

return 0;

}

output constant string retain count: ffffffff

string managed by the pool retain count: 1

self managed string retain count: 1

如果你執行這個程式,你會發現幾件事:第一件事,str1 的 retainCount 為 ffffffff。

另一件事,雖然我只有 release str3,整個程式卻還是處於完美的記憶體管理下,原因是第一個常數字串已經自動被加到 autorelease pool 裡了。還有一件事,字串是由 stringWithString 產生的。這個 method 會產生一個 NSString class 型別的字串,並自動加進 autorelease pool。

千萬記得,要有良好的記憶體管理,像 [NSString stringWithString: @"String"] 這種 method 使用了 autorelease pool,而 alloc method 如 [[NSString alloc] initWithString: @"String"] 則沒有使用 auto release pool。

在 Objective-C 有兩種管理記憶體的方法, 1) retain and release or 2) retain and release/autorelease。

對於每個 retain,一定要對應一個 release 「或」一個 autorelease。

下一個範例會展示我說的這點。

基於 "Programming in Objective-C," Copyright © 2004 by Sams Publishing一書中的範例,並經過允許而刊載。

Fraction.h ...

+(Fraction*) fractionWithNumerator: (int) n denominator: (int) d;

...

Fraction.m ...

+(Fraction*) fractionWithNumerator: (int) n denominator: (int) d {

Fraction *ret = [[Fraction alloc] initWithNumerator: n denominator: d];

[ret autorelease];

return ret;

}

...

main.m #import #import "Fraction.h"

#import int main( int argc, const char *argv[] ) {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

Fraction *frac1 = [Fraction fractionWithNumerator: 2 denominator: 5];

Fraction *frac2 = [Fraction fractionWithNumerator: 1 denominator: 3];

// print frac 1

printf( "Fraction 1: " );

[frac1 print];

printf( "\n" );

// print frac 2

printf( "Fraction 2: " );

[frac2 print];

printf( "\n" );

// this causes a segmentation fault

//[frac1 release];

// release the pool and all objects in it

[pool release];

return 0;

}

output Fraction 1: 2/5

Fraction 2: 1/3

在這個例子裡,此 method 是一個 class level method。在物件建立後,在它上面呼叫 了 autorelease。在 main method 裡面,我從未在此物件上呼叫 release。

這樣行得通的原因是:對任何 retain 而言,一定要呼叫一個 release 或 autorelease。物件的 retainCount 從 1 起跳 ,然後我在上面呼叫 1 次 autorelease,表示 1 - 1 = 0。當 autorelease pool 被釋放時,它會計算所有物件上的 autorelease 呼叫次數,並且呼叫相同次數的 [obj release]。

如同註解所說,不把那一行註解掉會造成分段錯誤(segment fault)。因為物件上已經呼叫過 autorelease,若再呼叫 release,在釋放 autorelease pool 時會試圖呼叫一個 nil 物件上的 dealloc,但這是不允許的。最後的算式會變為:1 (creation) - 1 (release) - 1 (autorelease) = -1

管理大量暫時物件時,autorelease pool 可以被動態地產生。你需要做的只是建立一個 pool,執行一堆會建立大量動態物件的程式碼,然後釋放這個 pool。你可能會感到好奇,這表示可能同時有超過一個 autorelease pool 存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值