默認的情況下。property = Ivar + getter + setter
get set只能重寫一個。重寫兩個要@synthesize nameString = _nameString;
MRC下重寫set
-(void)setName:(NSString *)name
{
if (_name != name)
{
[_name release];
[name retain];
_name = name;
}
}
property屬性:
1.readonly
如果您不希望通過setter方法更改屬性,您可以向屬性聲明中添加一個屬性來指定它應該是只讀的。在這種情況下。readonly告訴編譯器只生成getter方法。不會生成setter方法。但是可以用KVC和Ivar進行賦值操作。
屬性默認是readwrite
- atomic
屬性默認為atomic。atomic比較慢。
即使從不同線程同時調用訪問器,合成的訪問器也要確保值總是由getter方法完全檢索或通過setter方法完全設置。(說人話??梢缘玫酵暾膙alue和完整的set value)
因為原子訪問器方法的內部實現和同步是私有的,所以不可能將合成的訪問器與您自己實現的訪問器方法組合在一起。例如,如果您嘗試為原子的readwrite屬性提供自定義setter,但讓編譯器合成getter,那么您將得到編譯器警告。 - nonatomic
您可以使用非原子屬性屬性來指定合成的訪問器直接設置或返回一個值,而不必保證從不同線程同時訪問相同的值會發生什么。因此,訪問非原子屬性要比訪問原子屬性快得多,并且可以將合成的setter和自己的getter實現結合起來:
4.weak & strong
__weak TestObj * weakObj = [NSObject new];
block = ^(){
__strong TestObj *strongObj = weakObj;
if(! strongObj) return;
NSLog(@"TestObj對象地址:%@",strongObj);
dispatch_async(dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{
for (int i = 0; i < 1000000; i++) {
// 模擬一個耗時的任務
}
NSLog(@"耗時的任務 結束 TestObj對象地址:%@",strongObj);
});
關于weak的實現。https://github.com/BiBoyang/Study/wiki/@property的研究(二)-weak關鍵字.
5.copy
但是NSMutableString用strong修飾。
@interface XYZBadgeView : NSView
@property NSString *firstName;
@property NSString *lastName;
@end
NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
self.badgeView.firstName = nameString;
[nameString appendString:@"ny"];
- unsafe_unretained
ARC下用__unsafe_unretained 替代__weak
有些不能被weak修飾的類比如:
NSATSTypesetter
,NSColorSpace
,NSFont
,NSMenuView
,NSParagraphStyle
,NSSimpleHorizontalTypesetter
, andNSTextView
.
使用alloc創建對象;Runtime負責釋放對象
您不能顯式調用dealloc,或實現或調用retain、release、retainCount或autorelease。
如果需要管理實例變量以外的資源,可以實現dealloc方法。您不必(實際上您不能)釋放實例變量,但是您可能需要調用[systemClassInstance setDelegate:nil]上的系統類和其他沒有使用ARC編譯的代碼。
ARC中的自定義dealloc方法不需要調用[super dealloc]
不能為訪問器提供以new開頭的名稱。這又意味著,例如,除非指定了不同的getter,否則不能聲明名稱以new開頭的屬性:
// Won't work:
@property NSString *newTitle;
// Works:
@property (getter=theNewTitle) NSString *newTitle;
__strong是默認值。只要有一個指向對象的強指針,對象就保持“活著”。
__weak指定了一個引用,它不能保持被引用對象的生命。當對象沒有強引用時,弱引用被設置為nil。
__unsafe_unretain指定一個引用,該引用不保存被引用的對象,當對象沒有強引用時不設為nil。如果它引用的對象被釋放,指針就會保持懸空狀態。
__autoreleasing用于表示通過引用(id *)傳遞的參數,并在返回時自動遞增。
兩種block解決循環引用的方式。
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler = ^(NSInteger result) {
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};
MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil;
};
MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler = ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
// ...
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// ...
}
else {
// Probably nothing...
}
};
__bridge_transfer或CFBridgingRelease將一個非Objective-C指針移動到Objective-C,并將所有權轉移到ARC。
__autoreleasing
- (BOOL)save:(NSError **)error;
其實,這個(NSError **)error相當于(NSError * __autoreleasing *)error,編譯器默認為其生成了__autoreleasing修飾符。
編譯器默認生成__autoreleasing修飾符的做法,也是在貫徹內存管理原則,即確保只有通過以alloc/new/copy/mutableCopy開頭的方法返回的對象才能被持有。
雖然當我們自己定義id *obj類型的參數時,也可以顯式指定它的所有權修飾符為其他,并通過編譯,但為了貫徹內存管理原則,還是應該將id *obj類型的參數的所有權修飾符指定為__autoreleasing。