如何在运行时以编程方式检测属性是否为IBOutlet?

Div*_*er0 5 unit-testing properties objective-c objective-c-runtime

我正在我的项目上设置单元测试,以确保所有UIViewController IBOutlets都连接到它们各自的Xib对象(即,在viewDidLoad之后不为零)。我正在考虑将协议与这些UIViewControllers一起使用所需的函数“ getAllOutletNames”,像这样:

-(NSArray*)getAllOutletNames
{
    return @[ @"outletproperty1", @"outletProperty2", ...];
}
Run Code Online (Sandbox Code Playgroud)

...然后使用[viewController valueForKey:outletName]确保所有这些都不为零。问题在于它有点笨拙。必须为添加到xib的每个插座更新“ getAllOutletNames”,这很容易被忽略。我希望以编程方式进行此操作,以便可以自动检测并迭代所有IBOutlet属性。

我在NSHipster的这篇文章(“属性支持的属性”的cmd + f)中读到了一个属性应用于IBOutlets(或者我不太理解的“属性支持的属性”)。

看来我可以使用此答案的一部分获取类中所有属性的列表,而我可以使用此答案的一部分获取其属性。但是,使用以下代码从IBOutlet属性与非IBOutlet属性输出属性,我没有发现任何区别:

const char * type = property_getAttributes(class_getProperty([self class], [outletName UTF8String]));
NSString * typeString = [NSString stringWithUTF8String:type];
NSArray * attributes = [typeString componentsSeparatedByString:@","];
NSLog(@"%@",attributes);
Run Code Online (Sandbox Code Playgroud)

IB插座

(
    "T@\"UILabel\"",
    "&",
    N,
    "V_titleLabel"
)
Run Code Online (Sandbox Code Playgroud)

非IB插座

(
    "T@\"UIView\"",
    "&",
    N,
    "V_programmaticallySetupView"
)
Run Code Online (Sandbox Code Playgroud)

是否有任何方法可以访问NSHipster文章中提到的“属性支持的属性”,或者以其他方式确定某个属性是否以编程方式是IBOutlet,还是我在这里吠叫了错误的树?

Ric*_*III 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
Run Code Online (Sandbox Code Playgroud)

这是由于分布式对象类型编码而起作用的,记录如下:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-BABHAIFA

您可以使用其中任何一个来表示您想要的方法,并且由于 iOS 上不存在分布式对象,因此编译器和运行时会忽略它们。