将C#泛型方法转换为Objective-C

3

长话短说:

我的同事向我求助。我是一名C#开发人员,他是一名iOS开发人员,互相阅读代码有时可以获得一些有益的见解。

他正在编写一些函数,需要返回一个基础类型为UITableViewCell的对象,并将整数作为输入。实际返回类型是UITableViewCell的子类。他问我是否知道比简单的switch语句更好的解决方案:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (row) {
        case 0: {
            NSString *CellIdentifier = @"personCell";

            PersonInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[PersonInfoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
            cell.selectionStyle = UITableViewCellSelectionStyleNone;

            return cell;
            break;
        }
        case 1: {
            NSString *CellIdentifier = @"photoCell";

            PhotoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[PhotoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
            cell.selectionStyle = UITableViewCellSelectionStyleNone;

            return cell;
            break;
        }
        default:
            return nil; //Don't care about this atm. Not the problem.
            break;
    }
}

我对C#的实现会是以下这样:

public UITableViewCell TableViewCellForRowAtIndexPath(UITableView tableView, NSIndexPath indexPath)
{
    switch(indexPath.row)
    {
        case 0:
        return MakeCell<PersonInfoCell>();
        case 1:
            return MakeCell<PhotoCell>();
        default:
            return null; //Still doesn't matter
    }
}


public TCell MakeCell<TCell>() where TCell : UITableViewCell, new()
{
    TCell cell = new TCell();
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

public class PersonInfoCell : UITableViewCell
{
    //Dont care about implementation yet....
    //TL;DR
}

public class PhotoCell : UITableViewCell
{
    //Dont care about implementation yet....
    //TL;DR
}

简短故事:

有人知道如何将我的C#通用代码转换为Objective-C等效代码吗?


更新1

我们基于Nicholas Carey的想法实现有误。


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (row) {
        case 0: {
            NSString *CellIdentifier = @"personCell";
PersonInfoCell *cell = (PersonInfoCell *)[self makeCell:CellIdentifier]; //使用 cell 执行 PersonInfoCell 相关操作 return cell; break; } case 1: { NSString *CellIdentifier = @"photoCell";
PhotoCell *cell = (PhotoCell *)[self makeCell:CellIdentifier]; //使用 cell 执行 PhotoCell 相关操作 return cell; break; } default: return nil; //暂时不关心此处,不是问题。 break; } }
- (id *)makeCell:(NSString *)cellIdentifier { id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[PhotoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; // <---- 这个方法如何知道我想要一个 PhotoCell? //PhotoCell??? } cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell; }
3个回答

1
在Objective-C中,类是一等构造,可以像任何其他对象一样传递和使用。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;
    Class cellClass = nil;
    switch (row) {
        case 0:
            cellIdentifier = @"personCell";
            cellClass = [PersonInfoCell class];
            break;
        case 1:
            cellIdentifier = @"photoCell";
            cellClass = [PhotoCell class];
            break;
        default:
            return nil; //Don't care about this atm. Not the problem.
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
        cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

如果您真的想要将工厂方法完全因素化,您可以像这样做:
- (UITableViewCell *)getOrCreateCellForTable:(UITableView *)tableView withIdentifier:(NSString *)cellIdentifier class:(Class)cellClass
{
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (cell == nil)
      cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

  cell.selectionStyle = UITableViewCellSelectionStyleNone;
  return cell;
}

如果您想摆脱成对的cellIdentifiercellClass参数,其中一个选项是在使用的每个单元格类上创建一个defaultIdentifier类方法(在C#中是static方法)。这样,您就可以将只类传递给工厂方法,而工厂方法可以查询类以获取正确的标识符。

我们对 David Mitchell 的代码进行了一些编辑,然后它就完美地运行了。请查看 @Apox 的回答获取完整的实现。 - SynerCoder

1
基于David Mitchell的代码,我们(Synercoder的同事)得出了这个版本,完美运行!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;
    Class cellClass = nil;
    switch (indexPath.row) {
        case 0: {
            cellIdentifier = @"personCell";
            cellClass = [PersonInfoCell class];
            PersonInfoCell *personInfoCell = (PersonInfoCell *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            personInfoCell.delegate = self;
            return personInfoCell;
        }
        case 1: {
            cellIdentifier = @"photoCell";
            cellClass = [LastMeasureMent class];
            LastMeasureMent *measurementCell = (LastMeasureMent *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            measurementCell.selectionStyle = UITableViewCellSelectionStyleBlue;
            return measurementCell;
        }
        default: {
            cellIdentifier = @"photoCell";
            cellClass = [LastMeasureMent class];
            LastMeasureMent *measurementCell = (LastMeasureMent *)[self getOrCreateCellForTable:tableView withIdentifier:cellIdentifier class:cellClass];
            measurementCell.selectionStyle = UITableViewCellSelectionStyleBlue;
            return measurementCell;
        }
    }


}

- (UITableViewCell *)getOrCreateCellForTable:(UITableView *)tableView withIdentifier:(NSString *)cellIdentifier class:(Class)cellClass
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
        cell = [[cellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

感谢David!

0

看看这个问题:在Objective-C中有强类型集合吗?

Objective-C是后期绑定和动态类型的,因此您不需要泛型。您可以向任何对象发送任何消息。它对它的处理取决于对象。具有静态类型的早期绑定语言,如C#,Java,C ++需要泛型。如果没有它们,该问题将无法轻易知道它可以或不能做什么与包含的对象。


如果我在Objective-C中创建一个名为MakeCell的方法,并将返回类型设置为id,然后在switch语句中将其转换为正确的类型。这是可能的...但是MakeCell方法如何知道在该方法中实例化什么?我如何将方法传递给MakeCell方法,以便它知道要创建PersonInfoCellPhotoCell - SynerCoder
我们添加了我们认为你想要的内容。你能详细说明一下我们实现中缺少了什么吗? - SynerCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接