首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果对象来自UIViewController,如何只获取我创建的自定义属性的名称(在运行时)?

如果对象来自UIViewController,如何只获取我创建的自定义属性的名称(在运行时)?
EN

Stack Overflow用户
提问于 2016-05-02 16:44:32
回答 1查看 212关注 0票数 2

我在视图控制器中实现了以下代码,该视图控制器被定义为符合UICollectionViewDelegateUICollectionViewDataSource

代码语言:javascript
复制
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]];
    }
}

当我这样做时,我不仅看到了我的自定义属性,而且还看到了这些协议引入的一些属性,即:hashsuperclassdescriptiondebugDescription

如何仅显示来自子类的属性,而不是那些协议引入的属性?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-02 18:09:08

class_copyPropertyList方法将只返回为类声明的属性,而不是为超类声明的属性。正如class_copyPropertyList的标题所述,它返回

类型为objc_property_t的指针数组,用于描述类声明的属性。超类声明的任何属性都不包括在内。

但问题是,您已经将类定义为符合UICollectionViewDataSourceUICollectionViewDelegate。因此,这些协议引入的属性被解释为子类的属性,而不是某些超类的属性。

最简单的解决方案是删除这些协议声明,然后错误就消失了。

如果您不想删除这些协议声明(例如,您希望仍然享受这些协议方法的代码完成),则可以创建一个符合这些协议的抽象类,然后再将其子类。例如:

代码语言:javascript
复制
@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

和:

代码语言:javascript
复制
@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

这里唯一的缺点是,如果您不能对所需的方法进行子类,编译器就不会警告您。但是,至少您会得到一个运行时故障/警告来描述问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36987435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档