将c#泛型方法转换为objective-C
本文关键字:objective-C 转换 泛型方法 | 更新日期: 2023-09-27 18:14:57
说来话长:
我的一个同事向我寻求一点帮助。我是c#开发人员,他是iOS开发人员,阅读彼此的代码有时会让我们有一些很好的见解。他正在编写一个函数,该函数需要返回一个基类型为UITableViewCell
的对象,并以整数作为输入。实际的返回类型是UITableViewCell
的一个子类。他问我是否有一个更好的解决方案,而不是一个简单的开关,像这样:
- (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];
//Do PersonInfoCell specific stuff with cell
return cell;
break;
}
case 1: {
NSString *CellIdentifier = @"photoCell";
PhotoCell *cell = (PhotoCell *)[self makeCell:CellIdentifier];
//Do PhotoCell specific stuff with cell
return cell;
break;
}
default:
return nil; //Don't care about this atm. Not the problem.
break;
}
}
- (id *)makeCell:(NSString *)cellIdentifier
{
id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[PhotoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; // <---- how does this method know it is a PhotoCell I want?
//PhotoCell???
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
标题>
在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;
}
如果您想摆脱成对的cellIdentifier
和cellClass
参数,一个选项是在您使用的每个单元格类上创建defaultIdentifier
类方法(用c#的说法是static
方法)。这样,您就可以只将类传递给工厂方法,而工厂方法可以查询类以获得正确的标识符。
基于David Mitchell的代码,我们(synnercoder的同事)想出了这个,工作完美!
- (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;
}
谢谢大卫!
看这个问题:Objective-C中有强类型集合吗?
Objective-C是后绑定和动态类型的,所以你不需要泛型。您可以向对象发送任何消息。它用它做什么取决于对象。具有静态类型的早期绑定语言(如c#、Java、c++)需要泛型。如果没有它们,问题就不会[容易]知道它对所包含的对象能做什么或不能做什么。