今天发现UITableView的分类中有这么一段代码,有高手大大解释下么?谢谢 @interface NSIndexPath (UITableView) + (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section; @property(nonatomic,readonly) NSInteger section; @end |
|
10分 |
你可以在category的头文件中定义property. 编译器不会报错。但在实例中你是找不到你在category中扩展的属性。这就是我们说不能在category中定义属性和成员变量的原因(其实不是不能)。但我们可以在category的实现文件.m中来设置扩展属性的getter,setter 方法,但我们需要利用runtime.h提供的 objc_getAssociatedObject / objc_setAssociatedObject 方法来模拟生成实例变量。
可以参考:http://sjpsega.com/blog/2014/04/07/category-with-instance-variables/ |
10分 |
能的,我自己就经常这样写,主要是对外部提供一个只读属性,内部的实现很简单:
外部的.h文件: @interface NSIndexPath (UITableView) @property(nonatomic,readonly) NSInteger section; @property(nonatomic,readonly) NSInteger row; @end 内部的.m文件: @interface NSIndexPath (UITableView) @property(nonatomic,assign) NSInteger section; // 注意,内部用assign @property(nonatomic,assign) NSInteger row; // 注意,内部用assign @end 我与楼上的见解不同,首先不需要objc_getAssociatedObject、objc_setAssociatedObject方法(使用还得加runtime库,而Swift不支持),其实是做轻量级的接口很容易,苹果的框架大量地用到了这种方式 |
非常感谢版主的回答,但是。。。 @interface NSIndexPath (UITableView) @property(nonatomic,readonly) NSInteger section; // 这里会定义section实例变量么? @property(nonatomic,readonly) NSInteger row; @end @interface NSIndexPath (UITableView) @property(nonatomic,assign) NSInteger section; // 注意,内部用assign // 还是在这里定义的实例变量? @property(nonatomic,assign) NSInteger row; // 注意,内部用assign @end 这样如何改变section和row的值么?section和row用点语法赋值显示没定义。。。 @interface NSIndexPath (UITableView) { NSInteger section; NSInteger row; } @end |
|
这两个地方都是申明,两次申明都会指向内部的一个实例变量,如_row,其实在.m里面你可以不写这个类别:
@interface NSIndexPath (UITableView) @property(nonatomic,assign) NSInteger section; // 注意,内部用assign // 还是在这里定义的实例变量? @property(nonatomic,assign) NSInteger row; // 注意,内部用assign @end 照样可以通过_row、_section来给变量赋值,而且这两个变量对外部是不可见的,所以外部只能通过.row、.section来取值。 协议(或者说接口)是不能有【实例变量】的,你通过property设置的属性变量,其实是在实现接口的对象身上。 |