gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 12:01:04 24 4
gpt4 key购买 nike

我在定义为符合 UICollectionViewDelegateUICollectionViewDataSource 的 View Controller 中实现了以下代码:

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]];
}
}

当我这样做时,我不仅会看到我的自定义属性,还会看到那些协议(protocol)引入的一些属性,即:hashsuperclassdescriptiondebugDescription

如何只显示子类的属性,而不显示那些协议(protocol)引入的属性?

最佳答案

class_copyPropertyList 方法将只返回为类声明的属性,而不返回为父类(super class)声明的属性。正如 class_copyPropertyList 的 header 所说,它返回

An array of pointers of type objc_property_t describing the properties declared by the class. Any properties declared by superclasses are not included.

但问题是您定义的类符合 UICollectionViewDataSourceUICollectionViewDelegate。因此,这些协议(protocol)引入的属性被解释为您的子类的属性,而不是某些父类(super class)的属性。

最简单的解决方案是删除那些协议(protocol)声明,然后错误就会消失。

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

@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

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

关于ios - 如果来自 UIViewController 的对象如何只获取我创建的自定义属性的名称(在运行时)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36987435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com