<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMSBpZD0="1-基本原理">1 基本原理
對野指針發送消息 這種錯誤行為在進行時進行報錯,需要設置 Xcode
為了確定你的代碼在編譯時出現問題,則可以使用 Clang Static Analyzer ,內置在Xcode中。
許多工具和技術的技術說明在 Technical Note TN2239 中有描述,iOS Debugging Magic ,特別是使用的 NSZombie ,以幫助找到還未釋放的對象。 您可以使用儀器來跟蹤引用計數的事件,並查找內存洩漏。請參閱 Collecting Data on Your App如果你有個Objective-C對象類型的成員變量 ,就必須管理這個成員變量的內容,比如有個 NSNumber *count
@interface Counter : NSObject @property (nonatomic, retain) NSNumber *count; @end;
- (NSNumber *)count { return _count; }
- (void)setCount:(NSNumber *)newCount { [newCount retain]; [_count release]; // Make the new assignment. _count = newCount; }
- (void)reset { NSNumber *zero = [[NSNumber alloc] initWithInteger:0]; [self setCount:zero]; [zero release]; }
- (void)reset { NSNumber *zero = [NSNumber numberWithInteger:0]; [self setCount:zero]; }
- init { self = [super init]; if (self) { _count = [[NSNumber alloc] initWithInteger:0]; } return self; }
- initWithCount:(NSNumber *)startingCount { self = [super init]; if (self) { _count = [startingCount copy]; } return self; }
- (void)dealloc { [_count release]; [super dealloc]; }
@interface Person : NSObject // 返回BOOL類型的方法名一般以is開頭 @property (getter = isRich) BOOL rich; // @property (nonatomic, assign, readwrite) int weight; // setWeight: // weight // @property (readwrite, assign) int height; @property (nonatomic, assign) int age; @property (retain) NSString *name; @end
對於循環依賴關系來說,比方A類引用B類,同時B類也引用A類
#import "B.h" @interface A : NSObject { B *b; } @end
#import "A.h" @interface B : NSObject { A *a; } @end
這種代碼編譯會報錯,當使用@class 在兩個類相互聲明,就不會出現編譯報錯
用法概括使用 @class 類名;就可以引用一個類,說明一下它是一個類
和 #import區別#import 方法會包含被引用類的所有信息,包括被引用類的變量和方法;@class 方式只是告訴編譯器在 A.h 文件中 B *b 只是類的聲明,具體這個類有什麼信息,這裡不需要知道,等實現文件中真正要用到的時候,才會真正去查看B類中的信息。
如果有上百個頭文件都 #import 了同一個文件,或者這些文件依次被#import,那麼一旦最開始的頭文件稍有改動,後面引用到這個文件的所有類都需要重新編譯一遍,這樣的效率比較差,相對來說,使用 @class 方式就不會出現這種問題了。
在 .m 實現文件中,如果需要引用到被引用類的實體變量或者方法時,還需要使用 #import 方式引入被引用類。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [pool release]; // [pool drain];iOS 5.0後
@autoreleasepool { }在程序運行過程中,可以創建多個自動釋放池,它們是以棧的形式存在內存中 Objective-C對象只需要發送一條 autorelease 消息,就會把這個對象添加到最近的自動釋放池中(棧頂的釋放池)
以前:
Book *book = [[Book alloc] init]; [book release];
現在:
Book *book = [[[Book alloc] init] autorelease]; // 不要再調用 [book release];一般可以為類添加一個快速創建對象的類方法
+ (id)book { return [[[self alloc] init] autorelease]; // 上面這行本來可以寫成 return [[[Book alloc] init] autorelease]; // 但是這樣無法滿足Book子類的創建需求,所以最好都寫成 self }
外界調用 [Book book] 時,根本不用考慮在什麼時候釋放返回的 Book 對象。
NSNumber *n = [NSNumber numberWithInt:100]; NSString *s = [NSString stringWithFormat:@"jack"];
@autoreleasepool { // 1 Person *p = [[[Person alloc] init] autorelease]; // 0 [p release]; }
@autoreleasepool { Person *p = [[[[Person alloc] init] autorelease] autorelease]; }