關于類目(分類)能不能或者說應不應該添加屬性,本文不做討論。只是介紹利如何用運行時為類添加屬性。
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
/**
* Returns the value associated with a given object for a given key.
*
* @param object The source object for the association.
* @param key The key for the association.
*
* @return The value associated with the key \e key for \e object.
*
* @see objc_setAssociatedObject
*/
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
/**
* Removes all associations for a given object.
*
* @param object An object that maintains associated objects.
*
* @note The main purpose of this function is to make it easy to return an object
* to a "pristine state”. You should not use this function for general removal of
* associations from objects, since it also removes associations that other clients
* may have added to the object. Typically you should use \c objc_setAssociatedObject
* with a nil value to clear an association.
*
* @see objc_setAssociatedObject
* @see objc_getAssociatedObject
*/
OBJC_EXPORT void objc_removeAssociatedObjects(id object)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
以上三個為<objc/runtime.h>里提供的在運行時處理屬性的方法。
·第一個是添加關聯(lián)策略
·第二個是獲取關聯(lián)策略
·第三個是移除所有關聯(lián)策略(慎用?。。。?br>
·如果需要移除某個關聯(lián)策略,那么可以使用第一個方法,傳入參數(shù)為nil即可。
網上已經有大量的相關的方法。但是大多是對象類型,缺少基本數(shù)據(jù)類型的添加。
下面就是以BOOL類型為例子,進行相關的處理。
const void *theKey = @"theKey";
- (void)setYourProperty:(BOOL)yourPropertyName {
objc_setAssociatedObject(self, theKey, @(isXXX), OBJC_ASSOCIATION_ASSIGN);
}
- (BOOL)yourProperty {
return [objc_getAssociatedObject(self, theKey) boolValue];
}
上面是利用運行時方法為某個類添加一個BOOL類型的屬性。下面介紹常規(guī)的BOOL屬性賦初值的方法。利用懶加載給一個BOOL屬性賦一個初值。(ARC環(huán)境)
初值為NO的情況:
- (BOOL)isXXX {
if (!_isXXX) {
_isXXX = NO;
}
return _isXXX;
}
初值為YES的情況:
因為布爾屬性在沒有初值的情況下值并不明確,類似于NO的情況,那么可以利用dispatch_once_t函數(shù)進行處理。雖然官方API里面解釋的是"Use lazily initialized globals instead",但是布爾類型基本數(shù)據(jù)類型,使用的是assign來修飾。不會產生內存問題。
- (BOOL)isXXX {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_isXXX = YES;
});
return _isXXX;
}