我正在为我的项目设置单元测试,以确保所有UIViewController IBOutlets都连接到它们各自的Xib对象(即,在viewDidLoad之后不是nil。)我正在考虑将协议应用于具有所需功能的这些UIViewControllers“ getAllOutletNames“,就像这样:
-(NSArray*)getAllOutletNames
{
return @[ @"outletproperty1", @"outletProperty2", ...];
}
...然后使用[viewController valueForKey:outletName]确保这些都不是零。这个问题是它有点笨拙;必须为添加到xib的每个插座更新“getAllOutletNames”,这很容易被忽略。我更喜欢以编程方式执行此操作,以便可以自动检测和迭代所有IBOutlet属性。
我在this NSHipster article(cmd + f表示“属性支持的属性”)中读取了一个属性应用于IBOutlets(或者,一个“属性支持的属性”,我不太明白。)
看起来我可以使用this answer的一部分获取类中所有属性的列表,并且我可以使用this answer的一部分来获取它们的属性。但是,使用以下代码从IBOutlet打印出属性与非IBOutlet属性,我发现没有任何区别:
const char * type = property_getAttributes(class_getProperty([self class], [outletName UTF8String]));
NSString * typeString = [NSString stringWithUTF8String:type];
NSArray * attributes = [typeString componentsSeparatedByString:@","];
NSLog(@"%@",attributes);
IBOutlet中
(
"T@\"UILabel\"",
"&",
N,
"V_titleLabel"
)
非IBOutlet中
(
"T@\"UIView\"",
"&",
N,
"V_programmaticallySetupView"
)
有没有办法访问NSHipster文章提到的这个“属性支持的属性”,或以其他方式确定某个属性是否是一个IBOutlet,或者我在这里咆哮错误的树?
答案 0 :(得分:2)
这是我之前用来将方法标记为特殊的技巧,它也可以用于属性:
#import <objc/runtime.h>
#define synthesize_nooutlet(name) \
synthesize name=_ ## name; \
- (oneway id)name { \
return _ ## name; \
}
@interface ViewController ()
@property (nonatomic, strong) UIView *theView;
@end
@implementation ViewController
@synthesize_nooutlet(theView);
- (void) viewDidLoad {
[super viewDidLoad];
[self.theView setBackgroundColor:[UIColor clearColor]];
char returnType;
method_getReturnType(class_getInstanceMethod([self class], @selector(theView)), &returnType, 1);
if (returnType == 'V') {
// Do stuff
}
}
@end
这是因为分布式对象类型编码,这里记录:
您可以使用其中任何一个来表示您想要的方法,并且因为iOS上不存在分布式对象,编译器和运行时只是忽略它们。