4

Я настраиваю модульные тесты в своем проекте, чтобы убедиться, что все UIViewController IBOutlets подключены к их соответствующим объектам Xib (т. Е. Не нуль после viewDidLoad.) Я рассматривал возможность применения протокола к этим UIViewControllers с требуемой функцией «getAllOutletNames» », например, так:Как определить, является ли свойство IBOutlet программным способом во время выполнения?

-(NSArray*)getAllOutletNames 
{ 
    return @[ @"outletproperty1", @"outletProperty2", ...]; 
} 

... а затем, используя [ViewController valueForKey: outletName], чтобы убедиться, что ни один из них не равны нулю. Проблема в том, что это немного громоздко; «getAllOutletNames» необходимо обновить для каждого выхода, добавленного в xib, что можно легко упустить. Я бы предпочел сделать это программным способом, чтобы все свойства 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

(
    "[email protected]\"UILabel\"", 
    "&", 
    N, 
    "V_titleLabel" 
) 

Non-IBOutlet

(
    "[email protected]\"UIView\"", 
    "&", 
    N, 
    "V_programmaticallySetupView" 
) 

Есть ли способ получить доступ к этому атрибуту с атрибутом, который соответствует N В статье Shipster упоминалось или иным образом определялось, является ли свойство программным обеспечением IBOutlet программным путем, или я беру здесь неправильное дерево?

+0

По шкале от 1 до 10, насколько вы напуганы объектив-C++? У меня есть решение, если вам все равно. –

+0

Не слишком напуган, на самом деле мне нравится любая возможность узнать больше о внутренностях :) Так может, 3/10? – DivideByZer0

ответ

1

Вот трюк, который я использовал раньше, чтобы отметить методы, как особый, он может быть принят к свойствам, а также:

#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 

Это работает из-распределенных объектов типа кодировок, документированные здесь:

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

вы можете использовать любого из них для обозначения методов, однако вы хотели бы, и, как распределенные объекты не существуют на прошивке, среда выполнение компилятора & просто игнорировать их.

+0

Очень интересно, и умно! Благодаря! – DivideByZer0