Objective-C 給分類添加“屬性”——關聯對象

來源:互聯網
上載者:User

標籤:關聯對象

給分類添加“屬性”

咱們知道,分類中可以添加方法,卻無法添加屬性。那咱們有其他的方法來實現嗎?
先來看看下面這段代碼:

@interface UIView (nl_Frame)@property (nonatomic, assign) CGFloat nl_width;@end
 @implementation UIView (nl_Frame)- (void)setNl_width:(CGFloat)nl_width {  CGRect frame = self.frame;  frame.size.width = nl_width;  self.frame = frame;}- (CGFloat)nl_width {  return CGRectGetWidth(self.frame);}@end

在這裡給 UIView增加了一個寬度“屬性”:nl_width,而且為其實現了相應的 getter和 setter方法(nl_widthsetNl_width:)。這兩個方法實際上訪問的 frame“屬性”,為什麼給在這裡也打上雙引號?沒錯,frame也是定義在分類裡邊的:

@interface UIView(UIViewGeometry)@property(nonatomic) CGRect            frame;//...@end

可以看到,這種定義在分類裡的“屬性”,實際上是實現了相應的方法,並在方法裡邊通過訪問其它屬性來達到目的。這通常用來簡化某些操作,比如定義咱們這個分類後,擷取視圖的寬度只要view.nl_width就可以了,再不用CGRectGetWidth(view.frame)來得到寬度,而且可讀性也增強了很多。

再來看看這個需求:在 sqlite中,第一個表如果在沒有指定主鍵的情況下,那預設就會定義一個主鍵rowid。咱們就把這個 rowid直接放到 NSObject裡邊,作為屬性,那麼任何對象也會有這個主鍵rowid了。但是這個rowid卻無法像上邊的nl_width一樣通過訪問其它屬性來達到目的。那該怎麼辦?

關聯對象

本節的主角出場了:關聯對象
在使用關聯對象之前,得先引入標頭檔:

#import <objc/runtime.h>

可以在該標頭檔中找到三個允許你將任何索引值在運行時關聯到對象上的函數:

objc_setAssociatedObject       // 設定關聯對象objc_getAssociatedObject       // 擷取關聯對象objc_removeAssociatedObjects   // 移除關聯對象

既然有了這個工具,那麼咱們再來看看:

@interface NSObject (nl_sqlite)@property (nonatomic, assign) NSUInteger rowid;@end
@implementation NSObject (nl_sqlite)static void *nl_sqlite_rowid_key = &nl_sqlite_rowid_key;- (void)setRowid:(NSUInteger)rowid {  objc_setAssociatedObject(self, nl_sqlite_rowid_key, @(rowid), OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (NSUInteger)rowid {  return [objc_getAssociatedObject(self, nl_sqlite_rowid_key) unsignedLongValue];}@end

上面的代碼,就是通過關聯對象給NSObject增加了一個rowid“屬性”。關聯對象在使用時,需要咱們提供一個指標,即key,用來識別被關聯的對象。咱們這裡的key就是一個null 指標:nl_sqlite_rowid_key。當然,你也可以@selector(rowid)來作為 key(常用)。
於是,就可以這麼來用了:

id person = [NSObject new];person.rowid = 1;

很爽吧!以後就可以給已有類添加“屬性”了。這可是一個很強大的功能喲,如果你查看過一些強大的第三方庫的話,就會發現,這是一個常用的技巧。

為什麼分類無法添加屬性

待寫

關聯對象的基本原理

待寫

Objective-C 給分類添加“屬性”——關聯對象

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.