定制课程&在Objective-C中转换条件语句

时间:2011-12-23 00:09:12

标签: objective-c ios casting

我现在遇到了这个问题两次,我很想知道是否有正确的方法让下面的例子工作。我知道还有其他方法/解决方法可以做同样的事情,但我想知道为什么编译器不能识别我的演员,如果我错过了一些明显的东西。

假设我有两个表视图,我需要提供不同的样式标题视图。 SectionHeaderViewA是一个带有自定义属性textLabelA的UIView子类,SectionHeaderViewB也是一个带有自定义属性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;
}

即使在我的headerView ivar中投射(SectionHeaderViewA *)和(SectionHeaderViewB *)之后,我仍然无法访问其各自的自定义属性。这就像编译器仍然将headerView视为未知/ id类型,但为什么?

3 个答案:

答案 0 :(得分:2)

演员阵容不在正确的位置。在发送相应的textLabel 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;  

移动演员表后,您将能够发送正确的信息。

答案 1 :(得分:1)

当你投射到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; 

或另一种可能性(可能过度设计问题)是使sectionHeaderViewAsectionHeaderViewB符合协议,然后你可以使它更整洁一点。

<强> SectionHeaderInterface.h

@protocol SectionHeaderInterface <NSObject>

@property (strong, nonatomic) UILabel *textLabel;

@end

<强> SectionHeaderView(A | B)·H

#import "SectionHeaderInterface.h"

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

// ... rest of interface

@end

<强> SectionHeaderView(A | B)的.m

@implementation SectionHeaderView(A|B)

@synthesize textLabel = _textLabel;

// ... rest of your class

@end

<强> YourController.m

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;

答案 2 :(得分:1)

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;