我在视图控制器中实现了以下代码,该视图控制器被定义为符合UICollectionViewDelegate和UICollectionViewDataSource
objc_property_t *properties = class_copyPropertyList(self, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
[properitiesList addObject:[NSString stringWithUTF8String:propName]];
}
}当我这样做时,我不仅看到了我的自定义属性,而且还看到了这些协议引入的一些属性,即:hash、superclass、description和debugDescription。
如何仅显示来自子类的属性,而不是那些协议引入的属性?
发布于 2016-05-02 18:09:08
class_copyPropertyList方法将只返回为类声明的属性,而不是为超类声明的属性。正如class_copyPropertyList的标题所述,它返回
类型为
objc_property_t的指针数组,用于描述类声明的属性。超类声明的任何属性都不包括在内。
但问题是,您已经将类定义为符合UICollectionViewDataSource和UICollectionViewDelegate。因此,这些协议引入的属性被解释为子类的属性,而不是某些超类的属性。
最简单的解决方案是删除这些协议声明,然后错误就消失了。
如果您不想删除这些协议声明(例如,您希望仍然享受这些协议方法的代码完成),则可以创建一个符合这些协议的抽象类,然后再将其子类。例如:
@interface AbstractViewControllerForCollectionView : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
@end
@implementation AbstractViewControllerForCollectionView
// we have to implement the required methods; let's just warn the developer if they accidentally fail to subclass
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSAssert(FALSE, @"this must be subclassed");
return 0;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSAssert(FALSE, @"this must be subclassed");
return nil;
}
@end和:
@interface ViewController : AbstractViewControllerForCollectionView
@property (nonatomic, strong) NSString *myPropertyName;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSArray *objects;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
NSLog(@"%@", [[self class] properties]);
}
+ (NSArray *)properties {
NSMutableArray *propertyList = [NSMutableArray array];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(self, &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if (propName) {
[propertyList addObject:[NSString stringWithUTF8String:propName]];
}
}
free(properties);
return propertyList;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.objects.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
// configure cell
return cell;
}
@end这里唯一的缺点是,如果您不能对所需的方法进行子类,编译器就不会警告您。但是,至少您会得到一个运行时故障/警告来描述问题。
https://stackoverflow.com/questions/36987435
复制相似问题