Пользовательские классы и приведение внутри условных операторов в Objective-C - PullRequest
0 голосов
/ 23 декабря 2011

Я уже дважды сталкивался с этой проблемой, и мне любопытно узнать, есть ли правильный способ заставить следующий пример работать.Я знаю, что есть другие способы / обходные пути для того же самого, но мне интересно, почему компилятор не распознает мое приведение, и если я здесь упускаю что-то очевидное.

Предположим, у меня есть два табличных представления с различным стилемзаголовки просмотров, которые мне нужно предоставить.SectionHeaderViewA является подклассом UIView с пользовательским свойством textLabelA, SectionHeaderViewB также является подклассом UIView с пользовательским свойством textLabelB.

В методе:

- (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 я все еще не могу получить доступ к их соответствующим пользовательским свойствам.Это похоже на то, что компилятор все еще видит headerView как неизвестный тип / id, но почему?

Ответы [ 3 ]

2 голосов
/ 23 декабря 2011

Состав не в правильном месте.Приведите headerView перед отправкой соответствующего сообщения textLabel A или B.

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 голос
/ 23 декабря 2011

тип 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;
1 голос
/ 23 декабря 2011

Ваш каст ничего не делает, так как вы кастуете в id.

Хотя ответ @ Шона работает и он делает единственный выход, он довольно уродлив, имея все фигурные скобки, я бы, наверное, выбрал

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 соответствовать протоколу, и тогда вы можете сделать его еще немного более аккуратным.

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...