我的一位同事向我求了一点帮助。我是一名C#开发人员,他是一名iOS开发人员,每次阅读代码都会给我们一些很好的见解。
他正在编写一些需要返回basetype 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 equilivant的方法?
基于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;
}
答案 0 :(得分: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;
}
如果你想摆脱配对的cellIdentifier
和cellClass
参数,一个选项就是创建一个defaultIdentifier
类方法(static
方法,在C#语言中)在您使用的每个单元类上。这样,您可以只将类传递给工厂方法,并且工厂方法可以在类中查询正确的标识符。
答案 1 :(得分: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;
}
谢谢大卫!
答案 2 :(得分:0)
请参阅此问题:Are there strongly-typed collections in Objective-C?
Objective-C是后期绑定和动态类型的,因此您不需要泛型。您可以将任何消息发送到对象。它用它做什么取决于对象。具有静态类型的早期语言(如C#,Java,C ++)需要泛型。没有它们,问题就不会[很容易]知道它对所包含的对象能做什么或不能做什么。