为什么 Objective-C 不能在受保护的函数指针中使用 'self' 对象?
Why the Objective-C cannot use 'self' object in protected function-pointer?
我想在 Objective-C 中使用 'protected' ,所以我写了 FatherView class 和 AView class :
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 class 中, _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 class 是 FatherView class' subclass :
@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 打印结果:空!
为什么? AView是FatherView的subclass,_test_one_view是FatherView的属性,_test_one_view是在FahterView的init方法中创建的,我想打印FahterView的属性(属性在AView中是_test_one_view) class,但是结果是null,为什么?
我不知道为什么...
我需要你的帮助,谢谢...
将选择器转换为函数指针是个问题。使用积木。
每个实例的函数指针都不是唯一的 - 它是指向所有实例的方法实现的指针,并且不会与它一起存储 "self" 指针。
问题是 testV_funcp_void
,
的声明类型
我们知道methodForSelector
returns的类型是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
我想在 Objective-C 中使用 'protected' ,所以我写了 FatherView class 和 AView class :
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 class 中, _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 class 是 FatherView class' subclass :
@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 打印结果:空!
为什么? AView是FatherView的subclass,_test_one_view是FatherView的属性,_test_one_view是在FahterView的init方法中创建的,我想打印FahterView的属性(属性在AView中是_test_one_view) class,但是结果是null,为什么?
我不知道为什么...
我需要你的帮助,谢谢...
将选择器转换为函数指针是个问题。使用积木。
每个实例的函数指针都不是唯一的 - 它是指向所有实例的方法实现的指针,并且不会与它一起存储 "self" 指针。
问题是 testV_funcp_void
,
我们知道methodForSelector
returns的类型是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