定制课程及;在Objective-C中转换内部条件语句

定制课程及;在Objective-C中转换内部条件语句,objective-c,ios,casting,Objective C,Ios,Casting,我现在两次遇到这个问题,很想知道是否有正确的方法让下面的示例工作。我知道做同样的事情还有其他方法/变通方法,但我想知道为什么编译器不识别我的角色转换,以及我是否遗漏了一些明显的东西 假设我需要提供两个具有不同样式标题视图的表视图SectionHeaderViewA是一个具有自定义属性textLabelA的UIView子类,SectionHeaderViewWB也是一个具有自定义属性textLabelB的UIView子类 在方法中: - (UIView*)tableView:(UITableVie

我现在两次遇到这个问题,很想知道是否有正确的方法让下面的示例工作。我知道做同样的事情还有其他方法/变通方法,但我想知道为什么编译器不识别我的角色转换,以及我是否遗漏了一些明显的东西

假设我需要提供两个具有不同样式标题视图的表视图
SectionHeaderViewA
是一个具有自定义属性
textLabelA
的UIView子类,
SectionHeaderViewWB
也是一个具有自定义属性
textLabelB
的UIView子类

在方法中:

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    id headerView;
    if (tableView.tag == TAG_A)
    {
        headerView = (SectionHeaderViewA*)[[SectionHeaderViewA alloc] init];
        headerView.textLabelA = ... // I am unable to access the custom property here even after casting (SectionHeaderViewA*) above.
    } else if (tableView.tag == TAG_B) {
        headerView = (SectionHeaderViewB*)[[SectionHeaderViewB alloc] init];
        headerView.textLabelB = ... // Same as above, even after casting the custom property is not recognised
    }
    return headerView;
}

即使在将(SectionHeaderViewA*)和(SectionHeaderViewB*)强制转换到我的headerView ivar后,我仍然无法访问它们各自的自定义属性。这就像编译器仍然将
headerView
视为未知的/id类型,但为什么呢?

您的cast在转换到
id
时没有做任何事情

虽然@sean的答案是有效的,而且是单出口的,但我可能会选择所有的花括号,这是非常难看的

id headerView = nil; // Initialize to nil... you may not go into either side of your if

if (TAG_A == tableView.tag) {  
    SectionHeaderViewA *sectionHeaderViewA = [[SectionHeaderViewA alloc] init];
    sectionHeaderViewA.textLabelA = ... 
    headerView = sectionHeaderViewA;
} else if (TAG_B == tableView.tag) {
    SectionHeaderViewB *sectionHeaderViewB = [[SectionHeaderViewB alloc] init];
    sectionHeaderViewB.textLabelB = ...
    headerView = sectionHeaderViewB;
}

return headerView; 
或者另一种可能性(可能是过度设计问题)是使
sectionHeaderViewA
sectionHeaderViewB
符合协议,然后您可以使其更整洁

节头接口.h

@protocol SectionHeaderInterface <NSObject>

@property (strong, nonatomic) UILabel *textLabel;

@end
#import "SectionHeaderInterface.h"

@interface SectionHeaderView(A|B) : UIView <SectionHeaderInterface>

// ... rest of interface

@end
YourController.m

@implementation SectionHeaderView(A|B)

@synthesize textLabel = _textLabel;

// ... rest of your class

@end
id<SectionHeaderInterface> headerView = nil; // Initialize to nil... you may not go into either side of your if

if (TAG_A == tableView.tag) {  
    headerView = [[SectionHeaderViewA alloc] init];
} else if (TAG_B == tableView.tag) {
    headerView = [[SectionHeaderViewB alloc] init];
}

headerView.textLabel.text = ...

return headerView;
id headerView=nil;//初始化为零。。。你不能进入你的if的任何一边
如果(TAG_A==tableView.TAG){
headerView=[[SectionHeaderViewA alloc]init];
}else if(TAG_B==tableView.TAG){
headerView=[[SectionHeaderViewB alloc]init];
}
headerView.textLabel.text=。。。
返回headerView;

当您在
id
中施法时,您的施法没有做任何事情

虽然@sean的答案是有效的,而且是单出口的,但我可能会选择所有的花括号,这是非常难看的

id headerView = nil; // Initialize to nil... you may not go into either side of your if

if (TAG_A == tableView.tag) {  
    SectionHeaderViewA *sectionHeaderViewA = [[SectionHeaderViewA alloc] init];
    sectionHeaderViewA.textLabelA = ... 
    headerView = sectionHeaderViewA;
} else if (TAG_B == tableView.tag) {
    SectionHeaderViewB *sectionHeaderViewB = [[SectionHeaderViewB alloc] init];
    sectionHeaderViewB.textLabelB = ...
    headerView = sectionHeaderViewB;
}

return headerView; 
或者另一种可能性(可能是过度设计问题)是使
sectionHeaderViewA
sectionHeaderViewB
符合协议,然后您可以使其更整洁

节头接口.h

@protocol SectionHeaderInterface <NSObject>

@property (strong, nonatomic) UILabel *textLabel;

@end
#import "SectionHeaderInterface.h"

@interface SectionHeaderView(A|B) : UIView <SectionHeaderInterface>

// ... rest of interface

@end
YourController.m

@implementation SectionHeaderView(A|B)

@synthesize textLabel = _textLabel;

// ... rest of your class

@end
id<SectionHeaderInterface> headerView = nil; // Initialize to nil... you may not go into either side of your if

if (TAG_A == tableView.tag) {  
    headerView = [[SectionHeaderViewA alloc] init];
} else if (TAG_B == tableView.tag) {
    headerView = [[SectionHeaderViewB alloc] init];
}

headerView.textLabel.text = ...

return headerView;
id headerView=nil;//初始化为零。。。你不能进入你的if的任何一边
如果(TAG_A==tableView.TAG){
headerView=[[SectionHeaderViewA alloc]init];
}else if(TAG_B==tableView.TAG){
headerView=[[SectionHeaderViewB alloc]init];
}
headerView.textLabel.text=。。。
返回headerView;
headerView的类型为“id”,这意味着它不知道您的额外属性等(演员阵容不会更改“headerView”的类型)

你可以这样做:

if (tableView.tag == TAG_A)
{
    SectionHeaderViewA* headerView = [[SectionHeaderViewA alloc] init];
    headerView.textLabelA = ...
    return headerView;
} else if (tableView.tag == TAG_B) {
    SectionHeaderViewB* headerView = [[SectionHeaderViewB alloc] init];
    headerView.textLabelB = ... 
    return headerView;
}
return nil;
headerView的类型是“id”,这意味着它不知道您的额外属性等(演员阵容不会更改“headerView”的类型)

你可以这样做:

if (tableView.tag == TAG_A)
{
    SectionHeaderViewA* headerView = [[SectionHeaderViewA alloc] init];
    headerView.textLabelA = ...
    return headerView;
} else if (tableView.tag == TAG_B) {
    SectionHeaderViewB* headerView = [[SectionHeaderViewB alloc] init];
    headerView.textLabelB = ... 
    return headerView;
}
return nil;

铸件位置不正确。在发送适当的文本标签A或B消息之前,请先播放headerView

id headerView;
if (tableView.tag == TAG_A)  
{  
    headerView = [[SectionHeaderViewA alloc] init];
    ((SectionHeaderViewA*)headerView).textLabelA = ... // I am unable to access the custom property here even after casting (SectionHeaderViewA*) above.
} else if (tableView.tag == TAG_B) {
    headerView = [[SectionHeaderViewB alloc] init];
    ((SectionHeaderViewB*)headerView).textLabelB = ... // Same as above, even after casting the custom property is not recognized
}
return headerView;  

移动演员阵容后,您将能够发送正确的消息。

演员阵容不在正确的位置。在发送适当的文本标签A或B消息之前,请先播放headerView

id headerView;
if (tableView.tag == TAG_A)  
{  
    headerView = [[SectionHeaderViewA alloc] init];
    ((SectionHeaderViewA*)headerView).textLabelA = ... // I am unable to access the custom property here even after casting (SectionHeaderViewA*) above.
} else if (tableView.tag == TAG_B) {
    headerView = [[SectionHeaderViewB alloc] init];
    ((SectionHeaderViewB*)headerView).textLabelB = ... // Same as above, even after casting the custom property is not recognized
}
return headerView;  


移动强制转换后,您将能够发送正确的消息。

您收到的错误消息是什么?是否导入了两个标题?Rog,当您检查参数“tableView”的类型时,调试器是否识别表视图的特定类型?不将
headerView
初始化为
nil
有点危险,因为您可能会返回垃圾。此外,如果您未使用ARC,这些视图应自动释放。编译器错误消息是
语义问题:在类型为“\u strong id”的对象上找不到属性“textlab”
您收到了什么错误消息?是否已导入这两个标题?Rog,检查参数“tableView”的类型时,调试器是否识别表视图的特定类型?如果不将
headerView
初始化为
nil
,则有点危险,因为可能会返回垃圾。如果您没有使用ARC,这些视图也应该自动释放。编译器错误消息是
语义问题:在类型为“\uu strong id”的对象上找不到属性“textlab”
强制转换不会更改headerView的类型。你说得对,我这样看是有道理的。我不太喜欢你的条件语句中的三个返回点,所以我要做的是在
if/else
外部声明
headerView
,然后在条件do
headerView=headerViewA
headerView=headerViewB
内部声明
return headerView
。我认为这个答案是正确的,但同时,请注意内存泄漏。
强制转换不会更改headerView的类型。
。你说得对,我这样看是有道理的。我不太喜欢你的条件语句中的三个返回点,所以我要做的是在
if/else
外部声明
headerView
,然后在条件do
headerView=headerViewA
headerView=headerViewB
内部声明
return headerView
。我认为这个答案是正确的,但同时,请注意内存泄漏。我的荣幸。出于好奇,为什么要使用两个具有不同UITextLabel的不同视图作为分区标题?我真的不知道,这只是一个人为的例子来阐明我的观点。但我不明白为什么不能有不同的格式和与之相关的其他子视图(在我的例子中,我有两个不同的标题视图,因为iPad版本有两个不同的表视图)。我很高兴。出于好奇,为什么要在分区标题中使用两个具有不同UITextLabel的不同视图?我真的不知道,它只是一个co