Ios iPad应用程序运行缓慢,一段时间后崩溃
按一下按钮,我的iPad应用程序慢了60多次,最后崩溃了 一开始,我的应用程序运行得很好,过了一段时间,它变得越来越慢 响应操作大约需要8到10秒,最后它会崩溃 我不知道这一切为什么会发生。 我在uiviewcontroller上使用collectionview,它的所有内容视图都是在custome cell类中创建的 在iPAd 2上使用仪器进行测试后,拍摄了这些屏幕照片。 现在我该怎么办。??你看到这里有什么问题吗 这里是UICollectionView单元格中的加号按钮,用于执行操作,按钮点击时间随机增加,达到300000毫秒以上 请注意-->主线程显示0.0毫秒 这是什么意思 请把我引向正确的方向 编辑 这是我在这些方法中点击按钮所做的代码Ios iPad应用程序运行缓慢,一段时间后崩溃,ios,iphone,ipad,profiling,instruments,Ios,Iphone,Ipad,Profiling,Instruments,按一下按钮,我的iPad应用程序慢了60多次,最后崩溃了 一开始,我的应用程序运行得很好,过了一段时间,它变得越来越慢 响应操作大约需要8到10秒,最后它会崩溃 我不知道这一切为什么会发生。 我在uiviewcontroller上使用collectionview,它的所有内容视图都是在custome cell类中创建的 在iPAd 2上使用仪器进行测试后,拍摄了这些屏幕照片。 现在我该怎么办。??你看到这里有什么问题吗 这里是UICollectionView单元格中的加号按钮,用于执行操作,按钮
// 'purchasedProduct' is NSMutuableDictionary
-(void)btnPlus:(id)sender event:(id)event
{
indexPaths = [[NSMutableArray alloc]init];
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:myCollection];
btnIndex = [myCollection indexPathForItemAtPoint: currentTouchPosition];
MyCell *cell = (MyCell*)[myCollection cellForItemAtIndexPath:btnIndex];
NSString *newCode = [productID objectAtIndex:btnIndex.row];
newQty = cell.cellQty.text;
newQty = [NSString stringWithFormat:@"%d",[newQty integerValue] + 1];
BOOL currentCellHasUpdates = purchasedProduct[newCode] != nil;
if (currentCellHasUpdates)
{
// Object Already Exist.......
[purchasedProduct setObject:newQty forKey:newCode];
prdID = newCode;
[self UpdateProduct];
}
else
{
// create new object........
[purchasedProduct setObject:newQty forKey:newCode];
prdID = newCode;
[self BuyProduct];
}
[indexPaths addObject:btnIndex];
[myCollection reloadItemsAtIndexPaths:indexPaths]; // I think problem is here.
}
CellForItemAtIndexPath方法是
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CellID" forIndexPath:indexPath];
[[cell cellBtnPlus] addTarget:self action:@selector( btnPlus:event:) forControlEvents:UIControlEventTouchUpInside];
[[cell cellBtnMinus] addTarget:self action:@selector(btnMinus:event:) forControlEvents:UIControlEventTouchUpInside];
BOOL currentCellHasUpdates = purchasedProduct[[productID objectAtIndex:indexPath.row]] != nil;
if (currentCellHasUpdates)
{
cell.cellQty.text = [purchasedProduct objectForKey: [productID objectAtIndex:indexPath.row]];
cell.cellQty.textColor = [UIColor blueColor];
}
else
{
cell.cellQty.textColor = [UIColor lightGrayColor];
cell.cellQty.text = @"0";
}
image = nil;
NSString *imageName =[[productID objectAtIndex:indexPath.row] stringByAppendingString:@".jpg"];
getImagePath = [documentsDirectory stringByAppendingPathComponent:imageName];
image = [UIImage imageWithData:[NSData dataWithContentsOfFile:getImagePath]];
if (image.size.width == image.size.height)
{
//set newSize
}
if (image.size.width < image.size.height)
{
//calculate newSize
}
else
{
//calculate newSize
}
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if (image.size.width == image.size.height)
{
//set imgRect
}
if (image.size.width < image.size.height)
{
//Calculations for imgRect
}
if (image.size.width > image.size.height)
{
//Calculations for imgRect
}
cell.myImageView.frame = imgRect;
cell.myImageView.image = image;
cell.lbl1.text = [[desc objectAtIndex:indexPath.row] capitalizedString];
cell.lbl2.text = [@"Box Qty:" stringByAppendingString:[boxQty objectAtIndex:indexPath.row]];
cell.lbl4.text = [[code objectAtIndex:indexPath.row] uppercaseString];
cell.lbl5.text = [@"Pack Qty:" stringByAppendingString:[packQty objectAtIndex:indexPath.row]];
BOOL isStarProduct = starProducts[[productID objectAtIndex:indexPath.row]] != nil;
if (isStarProduct)
{
cell.lbl6.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"star.png"]];
}
else
{
cell.lbl6.backgroundColor = [UIColor clearColor];
}
return cell;
}
我应该/可以在哪里改进我的代码?您的工具清楚地表明,
重新加载项的情况说明:
是导致性能不佳的罪魁祸首。这意味着集合视图要花很长时间才能将单元格出列
查看您的cellforrowatinexpath:
方法,您的循环似乎是一个有吸引力的赌注,表明您的性能受到了哪些影响。对于每个单元格,您都要遍历一系列产品,希望满足以下条件
if ([[productID objectAtIndex:indexPath.row] isEqualToString:[updatedCodes objectAtIndex:i]])
{
cell.cellQty.text = [updatedQty objectAtIndex:i];
cell.cellQty.textColor = [UIColor blueColor];
}
一旦此条件为真,您将更新单元,但您不会打破循环
这意味着,对于每个单元,您都要遍历整个数组!您应该做的是在if中放置一个break语句来中断循环
尽管如此,我认为我们可以做得更好。假设您有一个产品数组和一个更新的代码数组,您确实应该考虑将这些与字典匹配。字典是通过特定键获取对象的好方法。将数组视为字典,其中键是数组索引。因此,当您在索引0处获取对象时,实际上是在获取键为0的对象。因此,在您的示例中,productID自然可以是您的键,而值将是产品。这将允许您立即获取任何产品,如果您知道其对应的productID
因此,您需要一本包含所有产品的词典。然后你需要一本包含所有更新代码的字典。您可以让collection视图显示字典中的所有产品(NSDictionary的方法为“allValues”),也可以使用产品数组
因此,您需要的基本理念是:
NSDictionary*productsKeyedByID=[NSDictionary Dictionary Dictionary对象:productsArray forKeys:[productsArray valueForKey:@“productID]”\\其中productID是产品对象上的属性
MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CellID" forIndexPath:indexPath];
[[cell cellBtnPlus] addTarget:self action:@selector( btnPlus:event:) forControlEvents:UIControlEventTouchUpInside];
[[cell cellBtnMinus] addTarget:self action:@selector(btnMinus:event:) forControlEvents:UIControlEventTouchUpInside];
NSString *currentCellProductId = productsArray[indexPath.row];
//using the modern syntax - you could also use the objectForKey: method.
BOOL currentCellHasUpdates = updatedCodesKeyedByID[currentCellProductId] != nil;
if (currentCellHasUpdates) {
cell.cellQty.text = updatedCodesKeyedByID[currentCellProductId].quantity;
cell.cellQty.textColor = [UIColor blueColor];
} else {
cell.cellQty.textColor = [UIColor lightGrayColor];
cell.cellQty.text = @"0";
}
现在,在处理按钮点击时,您还可以利用字典的功能:
-(void)btnPlus:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:myCollection];
btnIndex = [myCollection indexPathForItemAtPoint: currentTouchPosition];
MyCell *cell = (MyCell*)[myCollection cellForItemAtIndexPath:btnIndex];
NSString *newCode = [productID objectAtIndex:btnIndex.row];
newQty = cell.cellQty.text;
if (updatedCodesKeyedByID[newCode] != nil)
{
//NSLog(@"Object Already Exist...");
id codeToUpdate = updatedCodesKeyedByID[newCode];
codeToUpdate.quantity++;
[self UpdateProduct]; // Open DB SQlite DB Connection and update Table Record and Close Connection.
}
else
{
updatedCodesKeyedByID[newCode] = //create new object
[self BuyProduct]; // Open DB SQlite DB Connection and update Table Record and Close Connection.
}
}
<强>注您可能需要考虑更改您的设计,以只包含一个字典包含产品,每个产品都有关联的数量。未设置时,默认值为0。这样,你只需要检查一本字典,它似乎满足了你在这篇文章中所做的事情;即更新项目的数量
编辑将此讨论转移到聊天室后,最后一个难题是调用UICollectionView的ReloadItemsAndExpaths:在PerformButUpdate块中。您的工具清楚地表明,
ReloadItemsAndExpaths:
是性能不佳的罪魁祸首。这意味着集合视图要花很长时间才能将单元格出列
查看您的cellforrowatinexpath:
方法,您的循环似乎是一个有吸引力的赌注,表明您的性能受到了哪些影响。对于每个单元格,您都要遍历一系列产品,希望满足以下条件
if ([[productID objectAtIndex:indexPath.row] isEqualToString:[updatedCodes objectAtIndex:i]])
{
cell.cellQty.text = [updatedQty objectAtIndex:i];
cell.cellQty.textColor = [UIColor blueColor];
}
一旦此条件为真,您将更新单元,但您不会打破循环
这意味着,对于每个单元,您都要遍历整个数组!您应该做的是在if中放置一个break语句来中断循环
尽管如此,我认为我们可以做得更好。假设您有一个产品数组和一个更新的代码数组,您确实应该考虑将这些与字典匹配。字典是通过特定键获取对象的好方法。将数组视为字典,其中键是数组索引。因此,当您在索引0处获取对象时,实际上是在获取键为0的对象。因此,在您的示例中,productID自然可以是您的键,而值将是产品。这将允许您立即获取任何产品,如果您知道其对应的productID
因此,您需要一本包含所有产品的词典。然后你需要一本包含所有更新代码的字典。您可以让collection视图显示字典中的所有产品(NSDictionary的方法为“allValues”),也可以使用产品数组
因此,您需要的基本理念是: