Почему Objective-C не может использовать объект self в защищенном указателе функции? - PullRequest
0 голосов
/ 11 января 2019

Я хочу использовать «защищенный» в Objective-C, поэтому я пишу класс FatherView и класс AView:

typedef NS_OPTIONS(NSInteger, DisplayViewT) {
    DisplayViewT_One ,
    DisplayViewT_Two ,
};

@interface FatherView : UIView{
@protected
    UIView *_test_one_view ;
    UIView *(*_testV_funcp_void)(DisplayViewT displayT) ;
}
@end

в классе FatherView свойство _testV_one_view является указателем на функцию, Вы можете увидеть реализацию FatherView:

@interface FatherView()
@property (nonatomic , strong) UIView *test_two_view ;
@end

@implementation FatherView

- (id) init
{
    self = [super init] ;
    if( self ){
        self->_test_one_view = [[UIView alloc] init] ;
        self.test_two_view = [[UIView alloc] init] ;       
        self->_testV_funcp_void = (UIView *(*)(DisplayViewT))[self methodForSelector:@selector(test_func_testV:)] ;
    }
    return self ;
}
- (UIView *)test_func_testV:(DisplayViewT)displayT
{
    UIView *displayV = nil ;
    switch (displayT) {
        case DisplayViewT_One:{
            displayV = self->_test_one_view ;
        }
            break;
        case DisplayViewT_Two:
        default:{
                displayV = self.test_two_view ;
            }
            break;
    }
    return displayV ;
}
@end

Класс AView является подклассом класса FatherView:

@interface AView : FatherView
- (void)exc_teest ;
@end
@implementation AView
- (void)exc_test
{
    UIView *oneV = self->_testV_funcp_void(DisplayViewT_One) ;
    NSLog(@"%@",oneV) ;
}
@end

Вопрос: у AView есть метод, имя метода - exc_test, Я вызываю метод (exc_test).

Но результат печати Xcode: null!

Почему? AView является подклассом FatherView, _test_one_view является свойством FatherView, _test_one_view создается в методе init FahterView, я хочу напечатать свойство FahterView (свойство _test_one_view) в классе AView, но результат равен нулю, почему?

Не знаю, почему ...

Я хочу вашей помощи, спасибо ...

Ответы [ 2 ]

0 голосов
/ 11 января 2019

проблема в объявлении типа testV_funcp_void,

мы знаем, что methodForSelector возвращает тип IMP, действительное IMP равно typedef id (*IMP)(id, SEL, ...), но теперь вы устанавливаете IMP в UIView *(*_testV_funcp_void)(DisplayViewT displayT)

правильный тип должен быть UIView *(*_testV_funcp_void)(UIView *v , SEL sel, DisplayViewT displayT), это правильный путь, следующий:

typedef NS_OPTIONS(NSInteger, DisplayViewT) {
    DisplayViewT_One ,
    DisplayViewT_Two ,
};


@interface FatherView : UIView{
@protected
    UIView *_test_one_view ;
//    UIView *(*_testV_funcp_void)(DisplayViewT displayT) ;
    UIView *(*_testV_funcp_void)(UIView *v , SEL sel, DisplayViewT displayT) ;
}
@end

@interface FatherView()
@property (nonatomic , strong) UIView *test_two_view ;
@end

@implementation FatherView

- (id) init
{
    self = [super init] ;
    if( self ){
        self->_test_one_view = [[UIView alloc] init] ;
        self.test_two_view = [[UIView alloc] init] ;
        self->_testV_funcp_void = (UIView *(*)(UIView *, SEL, DisplayViewT))[self methodForSelector:@selector(test_func_testV:)] ;
    }
    return self ;
}
- (UIView *)test_func_testV:(DisplayViewT)displayT
{
    UIView *displayV = nil ;
    switch (displayT) {
        case DisplayViewT_One:{
            displayV = self->_test_one_view ;
        }
            break;
        case DisplayViewT_Two:
        default:{
            displayV = self.test_two_view ;
        }
            break;
    }
    return displayV ;
}
@end

@interface AView : FatherView{
@protected

}
@end

@implementation AView

- (void)exc_test
{
    UIView *oneV = self->_testV_funcp_void(self, @selector(test_func_testV:),  DisplayViewT_One) ;
    NSLog(@"%@",oneV) ;
}

@end    
0 голосов
/ 11 января 2019

Приведение селектора к указателю на функцию является проблемой. Используйте блок.

Указатель функции не является уникальным для каждого экземпляра - он является указателем на реализацию метода для всех экземпляров и не хранит указатель «self» вместе с ним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...