Add a "property" to a category
We know that you can add methods to a category, but you can't add properties . Do we have another way to do that?
Let's take a look at the following code:
@interface UIView (nl_Frame)@property (nonatomicassignCGFloat 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 ( Span class= "Hljs-keyword" >self .frame );} @end
This adds a width "attribute" to UIView: Nl_width, and implements the appropriate getter and setter methods ( nl_width
,) for it setNl_width:
. These two methods actually access the frame
"Properties", why give a double quote here also? Yes, it frame
is also defined in the category:
@interface UIView(UIViewGeometry)@property(nonatomic) CGRect frame;//...@end
As you can see, the "attribute" of this definition in the classification actually implements the corresponding method and achieves the purpose by accessing other properties in the method. This is often used to simplify certain operations, such as defining our classification, to get the width of the view as long as view.nl_width
it is available, not CGRectGetWidth(view.frame)
to get the width, and to improve readability.
Let's take a look at this requirement: in SQLite, the first table will define a primary key by default if it is not given a primary key rowid
. Let's put this rowid
directly NSObject
inside, as a property, then any object will have this primary key rowid
. But this rowid
is not the same as the above nl_width
. By accessing other properties to achieve the goal. What should I do then?
Associating objects
The protagonist of this section has appeared: related objects
Before you can use the associated object, you have to introduce the header file:
#import <objc/runtime.h>
You can find three functions in this header file that allow you to associate any key value to an object at run time:
objc_setAssociatedObject // 设置关联对象objc_getAssociatedObject // 获取关联对象objc_removeAssociatedObjects // 移除关联对象
Now that we have this tool, let's look at it again:
@interface nsobject (nl_ SQLite ) @property (nonatomic , Span class= "Hljs-keyword" >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
The above code NSObject
adds an "attribute" to the associated object rowid
. When the associated object is in use, we need to provide a pointer, that is key
, to identify the object being associated. What we have here key
is a null pointer: nl_sqlite_rowid_key
. Of course, you can also @selector(rowid)
come as key
(commonly used).
So, you can use it this way:
id person = [NSObject new];person.rowid1;
It's cool! You can add "properties" to an existing class in the future. This is a very powerful feature yo, if you look at some of the powerful third party libraries, you will find that this is a common technique.
Why classification Cannot add attributes
Pending write
Fundamentals of Associated objects
Pending write
Objective-c adding "attributes" to a category--associative objects