Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 计算并存储UITableViewCell中正在使用的NSManagedObject的单元格标题和说明_Objective C_Core Data_Uitableview - Fatal编程技术网

Objective c 计算并存储UITableViewCell中正在使用的NSManagedObject的单元格标题和说明

Objective c 计算并存储UITableViewCell中正在使用的NSManagedObject的单元格标题和说明,objective-c,core-data,uitableview,Objective C,Core Data,Uitableview,我有这两个方法,它们为在协议中声明的单元格提供标题和描述 @protocol TableCellProtocol <NSObject> @optional @property(readonly,nonatomic,strong) NSString *titleForCell; @property(readonly,nonatomic,strong) NSString *descriptionForCell; @end 其中self.myVar是CoreData属性 此协议用于U

我有这两个方法,它们为在协议中声明的单元格提供标题和描述

@protocol TableCellProtocol <NSObject>

@optional
@property(readonly,nonatomic,strong) NSString *titleForCell;
@property(readonly,nonatomic,strong) NSString *descriptionForCell;

@end
其中
self.myVar
是CoreData属性

此协议用于UITableViewCell:

- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    id<TableCellProtocol> obj = [_fetchedResultsController objectAtIndexPath:indexPath];
    MyTableViewCell *cell = [table dequeueReusableCellWithIdentifier:@"tableCell"];
    cell.cellTitle.text=obj.titleForCell;
    cell.cellDescr.text=obj.descriptionForCell;

    return cell;
}
-(UITableViewCell*)tableView:(UITableView*)table cellForRowAtIndexPath:(NSIndexPath*)indexPath{
id obj=[\u fetchedResultsController objectAtIndexPath:indexath];
MyTableViewCell*单元格=[table dequeueReusableCellWithIdentifier:@“tableCell”];
cell.cellTitle.text=obj.titleForCell;
cell.cellDescr.text=obj.descriptionForCell;
返回单元;
}
虽然我没有内存泄漏或分配问题,但我发现这并不是很优雅,而且出于性能原因,性能相当差,因为每次显示单元格时,都会创建一个新的NSString

此外,相关属性在应用程序生命周期中可能会更改,因此,如果将标题和描述存储在某个位置,我需要在需要时刷新它们

我正在我的项目中使用ARC。

尝试以下方法:

您可以定义两个返回字符串的方法,而不是声明两个属性并定义它们的getter方法。并使用此设置tableViewCell的标题和说明

@protocol TableCellProtocol <NSObject>

@optional
-(NSString *) getTitleForCell;
-(NSString *) getDescriptionForCell;

@end




-(NSString*)getTitleForCell {
   return [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
}

-(NSString*)getDescriptionForCell {
  return [NSString stringWithFormat:@"%@ - %@",self.myVar3,self.myVar4];
}
@protocol TableCellProtocol
@可选的
-(NSString*)getTitleForCell;
-(NSString*)getDescriptionForCell;
@结束
-(NSString*)getTitleForCell{
返回[NSString stringWithFormat:@“%@-%@”,self.myVar1,self.myVar2];
}
-(NSString*)getDescriptionForCell{
返回[NSString stringWithFormat:@“%@-%@”,self.myVar3,self.myVar4];
}

让我知道这是否对您有效。谢谢。

您必须通过检查(cell==nil)是否重新使用tableview中的单元格

-(UITableViewCell*)tableView:(UITableView*)table cellForRowAtIndexPath:(NSIndexPath*)indexPath

{


}

关于您上面的评论,我将发布使用transient属性在NSManagedObject子类中存储自定义属性。这种方法在内存方面是非常有效的,因为托管对象上下文会一直保持在对象上,直到上下文被重置,并且如果发生某些更改,它会自动相应地更改属性。在您的情况下,每次创建或重用单元格时都必须创建字符串。但是,现在由于我们缓存了对象,一旦创建了瞬态属性,它就一直存在,并且没有任何内存开销。所以应该快得多

您可以按如下方式实现transient属性:

@implementation SomeManagedObject

   + (NSSet*)keyPathsForValuesAffectingValueForKey:(NSString *)key{
     if([key isEqualToString:@"cellTitle"]){
      return [NSSet setWithObjects:@"myVar1", @"myVar2", nil];
    }else if([key isEqualToString: @"cellDescription"]){
      return [NSSet setWithObjects:@"myVar3", @"myVar4", nil];
    }
     return [super keyPathsForValuesAffectingValueForKey:key];
   } 

  // You could either override the getter for the transient attribute like this

  - (NSString*)cellTitle{
   if(!_cellTitle){
    [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];
   }
   return _cellTitle;
  }

  // You could also override the awakeFromFetch method to create the transient attribute as

 - (void)awakeFromFetch{
    [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];  
    [super awakeFromFetch];
}

 // Also use the willTurnIntoFault/didTurnIntoFault method as

 - (void)didTurnIntoFault{
     [super didTurnIntoFault];
     [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];  
 }

@end

我希望这有帮助。谢谢

更好的方法是为对象创建一些瞬态属性,然后在自定义getter方法中使用create-dependent-values。这将在创建后保留该值,这是推荐的值。在这种情况下,当相关属性更改时,如何有效地刷新title和desc,您可以使用willTurnInfoFault/didTurnIntoFault方法清除瞬态属性,这应该可以做到。但是对象并不总是有故障。您所说的不总是有故障是什么意思。如果您认为属性发生更改并保存了上下文,那么这些方法肯定会被调用。这与我现在所做的相同,我没有存储title和desc。我想避免的是每次都创建一个新的NSString。您的意思是,如果存储值,则必须在重新加载表时刷新它们?我无法理解该问题。
dequeueReusableCellWithIdentifier
如果nib对象或类已注册到
RegisterNB:forCellReuseIdentifier:
registerClass:forCellReuseIdentifier:
,则不会返回
nil
。这似乎与问题无关。
id<TableCellProtocol> obj = [_fetchedResultsController objectAtIndexPath:indexPath];
MyTableViewCell *cell = [table dequeueReusableCellWithIdentifier:@"tableCell"];
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
    }
cell.cellTitle.text=obj.titleForCell;
cell.cellDescr.text=obj.descriptionForCell;

return cell;
@implementation SomeManagedObject

   + (NSSet*)keyPathsForValuesAffectingValueForKey:(NSString *)key{
     if([key isEqualToString:@"cellTitle"]){
      return [NSSet setWithObjects:@"myVar1", @"myVar2", nil];
    }else if([key isEqualToString: @"cellDescription"]){
      return [NSSet setWithObjects:@"myVar3", @"myVar4", nil];
    }
     return [super keyPathsForValuesAffectingValueForKey:key];
   } 

  // You could either override the getter for the transient attribute like this

  - (NSString*)cellTitle{
   if(!_cellTitle){
    [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];
   }
   return _cellTitle;
  }

  // You could also override the awakeFromFetch method to create the transient attribute as

 - (void)awakeFromFetch{
    [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];  
    [super awakeFromFetch];
}

 // Also use the willTurnIntoFault/didTurnIntoFault method as

 - (void)didTurnIntoFault{
     [super didTurnIntoFault];
     [sell willChangeValueForKey: @"cellTitle"]; 
     _cellTitle =  [NSString stringWithFormat:@"%@ - %@",self.myVar1,self.myVar2];
    [self didChangeValueForKey: @"cellTitle"];  
 }

@end