iOS使用Category新增@property變數
本文csdn地址:http://blog.csdn.net/game3108/article/details/51147941
由於Objective-C的動態語言特性,可以動態的建立類,新增屬性和方法。
Class demoClass = objc_allocateClassPair([NSObject class], "TestDemo", 0);
class_addMethod(demoClass, @selector(intro), (IMP)&selfIntro, "v@:");
class_addIvar(demoClass,"myVar", sizeof(id), 0, "@");
objc_registerClassPair(demoClass);
其中就有一個class_addIvar
可以動態新增變數。但class_addIvar
只能在動態建立類的時候增加變數,定義類是靜態建立的類則無法新增。
而Category只能新增方法,使用 @property 也是隻會生成setter和getter方法的宣告。具體原因請參考這篇文章,這文章詳細解釋了Category的實現,為什麼可以動態新增方法,和不能新增例項變數的原因,這裡也不多介紹了。
那如果確實想給Category增加一個@property的變數,應該如何去實現?
比如如下標頭檔案:
//
// UIView+Associate.h
// TouchPalDialer
//
// Created by game3108 on 16/3/30.
//
//
#import <UIKit/UIKit.h>
@interface UIView (Associate)
@property (nonatomic, assign) NSInteger associateLength;
@end
首先,先要了解
@property的本質其實是 ivar(例項變數)+getter+setter
那既然如此,重寫getter和setter方法,並且增加一個ivar的變數,就可以實現@property的功能
對於重寫getter和setter方法,可以用如下方式
//
// UIView+Associate.m
// TouchPalDialer
//
// Created by game3108 on 16/3/30.
//
//
#import "UIView+Associate.h"
@implementation UIView (Associate)
@dynamic associateLength;
- (NSInteger) associateLength{
NSLog(@"associate get");
return 0;
}
- (void) setAssociateLength:(NSInteger)associateLength{
NSLog(@"associate length : %d" , associateLength);
}
@end
但重寫getter和setter方法還是不夠,必須要建立一個例項變數,這樣,就用到了OC runtime動態繫結變數的方法:
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
這樣可以動態建立一個ivar的例項變數使用,如下:
//
// UIView+Associate.m
// TouchPalDialer
//
// Created by game3108 on 16/3/30.
//
//
#import "UIView+Associate.h"
#import <objc/runtime.h>
@implementation UIView (Associate)
@dynamic associateLength;
static char associateLengthKey;
- (NSInteger) associateLength{
return [(NSNumber *)objc_getAssociatedObject(self, &associateLengthKey) integerValue];
}
- (void) setAssociateLength:(NSInteger)associateLength{
objc_setAssociatedObject(self, &associateLengthKey, @(associateLength), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
測試程式碼
UIView *testView = [[UIView alloc]init];
NSLog(@"test number: %d", testView.associateLength);
testView.associateLength = 20;
NSLog(@"test number: %d", testView.associateLength);
輸出結果test number: 0 test number: 20
參考連結
1.刨根問底Objective-C Runtime(3)- 訊息 和 Category
2.Runtime-動態建立類新增屬性和方法
3.stackoverflow:objective-c-add-property-in-runtime
相關文章
- @property中的變數與_變數
- IOS category 與 extensioniOSGo
- iOS面試之@propertyiOS面試
- iOS底層原理-CategoryiOSGo
- iOS設計模式——CategoryiOS設計模式Go
- 使用property為類中的資料新增行為
- postman(四):新增變數Postman變數
- PropertyGrid控制元件 分類(Category)及屬性(Property)排序控制元件Go排序
- Category為什麼只能加方法不能加成員變數?Go變數
- iOS Extension Category Protrol 例子理解iOSGo
- [分享]iOS開發- iOS反射機制: objc_property_t的使用iOS反射OBJ
- Java環境變數新增Java變數
- iOS 用runtime為分類新增成員變數或屬性iOS變數
- iOS問題整理03----CategoryiOSGo
- iOS套路面試題之CategoryiOS面試題Go
- 關於iOS Class Category的整理iOSGo
- 【iOS】category重寫方法的呼叫iOSGo
- Category新增weak屬性的精簡版本Go
- ios SDWebImage新增頭部引數iOSWeb
- Grafana新增下拉框變數Grafana變數
- iOS 靜變數static、全域性變數extern、區域性變數、例項變數iOS變數
- iOS runtime 給 Category 加屬性iOSGo
- Runtime 系列 3-- 給 category 新增屬性Go
- Linux 新增環境變數和刪除環境變數Linux變數
- Android property屬性許可權新增Android
- python變數中self的新增Python變數
- Ubuntu新增刪除環境變數Ubuntu變數
- CentOS新增、刪除環境變數CentOS變數
- Linux - 新增PATH環境變數Linux變數
- VUE:vite新增環境變數(一)VueVite變數
- iOS @property 屬性相關的總結iOS
- CSS @property,讓不可能變可能CSS
- iOS - block變數捕獲原理iOSBloC變數
- Ubuntu環境變數——新增與刪除Ubuntu變數
- iOS可變引數(不定引數)的用法iOS
- iOS底層原理總結 - Category的本質iOSGo
- iOS中擴充套件機制Category和associativeiOS套件Go
- windows變數使用Windows變數