類屬性設定與修飾詞

A訫飛Flyme發表於2017-12-19

雪野
分塊書寫,可能有點亂可能有重複,內容還是很全的。 ###Delegate修飾詞 Delegate為了防止迴圈引用一般用weak和assign修飾,但這兩者是有區別的,比如說A物件的delegate就是一個viewController,並且viewController對A物件也強引用了.

  • 如果用weak修飾,那麼當viewController釋放後,A物件的delegate會自動置為nil
  • 如果用assign修飾,當viewController釋放後,A物件的delegate會變成野指標,要防止這種情況,就要重寫viewController的dealloc方法,手動將A物件的delegate置為nil.
- (void)dealloc{ 
self.A.delegate = nil; 
};
複製程式碼

ARC與MRC下有什麼不同?就是MRC下只能用assign修飾,而在ARC下既能用weak也能用assign,只是用assign要做多一定工作,在蘋果官方文件中,都是用的week修飾詞

UITableViewDelegate,UITableViewDataSource
@property (nonatomic, weak, nullable) id <UITableViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id <UITableViewDelegate> delegate;
複製程式碼

屬性 是可以說是面嚮物件語言中封裝的一個體現,在自定義類中設定 ‘屬性’ 就相當於定義了一個私有變數、設定器(setter方法)以及訪問器(getter方法),其中無論是變數的定義,方法的宣告和實現都是系統自動生成的並且經過了相應地記憶體管理和優化,無需開發者操心。 屬性的宣告: 屬性一般定義在類的介面,或類的延展內,並且放在方法的宣告之前,成員變數的宣告之後。屬性關鍵字是@property,括號內的是屬性的屬性,然後是變數的型別和名字,屬性的定義一般分為兩種情況,一種是非物件型別的變數,如int整型,使用assign,第二種是物件型別的變數(NSobject),使用retain或copy(delegate除外) @property和@synthesize幫我們輕易的生成物件的getter和setter方法來完成對物件的賦值和訪問。但是如果我們如果要動態設定物件的getter和setter方法可以使用@property和@dynamic組合。物件訪問方法property的屬性設定非常多。

###1.atomic 和 nonatomic atomic是預設的屬性,表示對物件的操作屬於原子操作,主要提供多執行緒訪問的安全。在多執行緒的下對物件的訪問都需要先上鎖訪問後再解鎖,保證不會同時有幾個操作針對同一個物件。使用atomic比nonatomic更耗費系統資源,訪問效能低。 nonatomic 表示訪問器的訪問不是原子操作,不支援多執行緒訪問安全,但是訪問效能高。

2.readwrite 和readonly

readwrite 是預設的屬性,表示可以對物件進行讀和寫,會生成物件相應的setter和getter方法。 **readonly **表示只允許讀取物件的值,只會生成物件的getter方法。

3. assign retain和copy

retain 表示對NSObject和及其子類物件release舊值,再retain新值,使物件的應用計數增加一。 此屬性只能使用於obejective-c型別物件,而不能用於Core Foundation物件。(retain會增加物件的引用計數,而基本資料型別或者Core Foundation物件都沒有引用計數,把物件新增到陣列中時,引用計數將增加1)。

-(void) setOldValue: (NSString*) newValue {
    if (newValue !=oldValue) {
        [oldValue release];
        oldValue = [newValue retain];
    }
}
複製程式碼

**assign ** 是預設屬性,只可以對基本資料型別(如CGFloat,NSInteger,Bool,int,代理物件)等使用。該方式會對物件直接賦值而不會進行retain操作。 **copy ** 表示重新建立一個新的計數為1的物件,然後釋放掉舊的值。 都知道retain是對指標的拷貝,copy是對內容的拷貝。 比如:NSString 物件的地址為0x100,其內容為“string”,如果使用copy到另外一個NSString物件,則會生成另外一個地址為0x110的物件,只不過內容仍然是‘string“。如果使用retain到另外一個NSString物件,則該物件的地址仍然為0x100,只不過該物件的計數變為2.

NSString、NSArray、NSDictionary 經常使用 copy 關鍵字,是因為他們有對應的可變型別:NSMutableString、NSMutableArray、NSMutableDictionary.
為確保物件中的屬性值不會無意間變動,應該在設定新屬性值時拷貝一份,保護其封裝性block,也經常使用 copy,關鍵字block。
使用 copy 是從 MRC 遺留下來的“傳統”,在 MRC 中,方法內部的 block 是在棧區的,使用 copy 可以把它放到堆區.
在 ARC 中寫不寫都行:對於 block 使用 copy 還是 strong 效果是一樣的,但是建議寫上 copy.!!!
複製程式碼
@property(copy)NSMutableArray *array;(這樣寫的問題)
複製程式碼

因為 copy 策略拷貝出來的是一個不可變物件,然而卻把它當成可變物件使用,很容易造成程式奔潰這裡還有一個問題. 該屬性使用了同步鎖,會在建立時生成一些額外的程式碼用於幫助編寫多執行緒程式,這會帶來效能問題. 通過宣告 nonatomic 可以節省這些雖然很小,但是不必要額外開銷,在 iOS 開發中應該使用 nonatomic 替代 atomic.

4.strong 和 weak

在ARC的模式下,物件宣告時需要加入strong和weak,方便記憶體的自動管理。預設情況下是strong型別。 strong 強引用,預設的屬性,類似於retain,其實是一個相對的概念,就是一個引用。如果有一個強引用持有該物件,則該物件就不能被釋放。預設的所有例項變數和區域性變數都是strong指標。 weak 弱引用,類似於assign,弱引用除了不決定物件的存亡外,其他與強引用相同。 即使一個物件被持有無數個弱引用,只要沒有強引用指向他,那麼其還是會被清除,它不是物件的擁有者。其值會在物件被釋放後自動設定為nil

delegate 代理屬性,代理屬性也可使用
assign自身已經對它進行一次強引用,沒有必要再強引用一次,此時也會使用 weak
自定義IBOutlet 控制元件屬性一般也使用weak;也可以使用 strong,但是建議使用 weak
複製程式碼

weak指標主要用於“父-子”關係,父親擁有一個兒子的strong指標,因此父親是兒子的所有者;但為了阻止所有權迴圈,兒子需要使用weak指標指向父親。典型例子是delegate模式,你的ViewController通過strong指標(self.view)擁有一個UITableView, UITableView的dataSource和delegate都是weak指標,指向你的ViewController ###weak 和 assign 的不同點

weak 在屬性所指的物件遭到摧毀時,系統會將 weak 修飾的屬性物件的指標指向 nil,在 OC 給 nil 發訊息是不會有什麼問題的;
assign 在屬性所指的物件遭到摧毀時,屬性物件指標還指向原來的物件,由於物件已經被銷燬,這時候就產生了野指標.
!!!如果這時候在給此物件傳送訊息,很容造成程式奔潰assigin 可以用於修飾非 OC 物件,而 weak 必須用於 OC 物件。
複製程式碼

###@synthesize 和 @dynamic 分別有什麼作用

  • @property 有兩個對應的詞,一個是@synthesize,一個是@dynamic。 如果@synthesize 和@dynamic 都沒寫,那麼預設的就是
@syntheszie var = _var;
複製程式碼
  • @synthesize 的語義是如果你沒有手動實現 setter 方法和 getter 方法,那麼編譯器會自動為你加上這兩個方法。
  • @dynamic 告訴編譯器:屬性的 setter 與 getter 方法由使用者自己實現,不自動生成。(當然對於 readonly 的屬性只需提供 getter 即可) 假如一個屬性被宣告為
  • @dynamic var;然後你沒有提供@setter 方法和@getter 方法,編譯的時候沒問題,但是當程式執行到 instance.var = someVar,由於缺 setter方法會導致程式崩潰; 或者當執行到 someVar = instance.var 時,由於缺 getter 方法同樣會導致崩潰.

iOS關於屬性關鍵字-轉載的 END

相關文章