尝试删除图片时崩溃

时间:2013-12-15 06:04:07

标签: ios objective-c crash

我只希望用户只需使用集合视图点击图片即可删除图片。我这样做了一个月,不能直截了当,甚至感到困惑。我的代码如下所示。我有时也会得到一个内存警告,如果我使用仪器应用程序查找详细信息,内存分配不会被释放,只是在崩溃之前建立起来。

- (void)viewDidLoad
{  Trash = [NSMutableArray array];
    filenames = [NSMutableArray new];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSArray *locationStrings = [[NSArray alloc]initWithObjects:@"Bottoms", @"Dress", @"Coats", @"Others", @"hats", @"Tops",nil ];
    for(NSString* location in locationStrings){
        NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
        NSError *error;
        NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fPath error:&error];
        collectionTrash.delegate =self;
        collectionTrash.dataSource=self;
        for(NSString *str in directoryContent){
            NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
            [filenames addObject:finalFilePath];
        }
    }

}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    NSLog(@"j");
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [filenames count];
    NSLog(@"b");


}



- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"ReuseID";
    TrashCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    UIImageView *imageInCell = (UIImageView*)[cell viewWithTag:1];

    NSString *cacheKey = filenames[indexPath.item];
    imageInCell.image = [self.imageCache objectForKey:cacheKey];

    if (imageInCell.image == nil) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            UIImage *image = [UIImage imageWithContentsOfFile:filenames[indexPath.item]];
            if (image) {
                [self.imageCache setObject:image forKey:cacheKey];
                dispatch_async(dispatch_get_main_queue(), ^{
                    TrashCell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
                    UIImageView *imageInCell = (UIImageView*)[updateCell viewWithTag:1];
                    imageInCell.image = image;
                });
            }
        });
    }

    return cell;
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"s:%d", [Trash count]);
    NSString *trashBin = [Trash objectAtIndex:indexPath.row];
    NSLog(@"k%@l",trashBin);
    [filenames removeObjectAtIndex:indexPath.row];
    [Trash removeObjectAtIndex:indexPath.row];
    [self deleteMyFiles:trashBin];
    [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil]];
}
NSString *myFileName;
-(void) deleteMyFiles:(NSString*)filePath {
    NSError *error;

    if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];

    } else {
        NSLog(@"%@",filePath);
    }
}



- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    [self.imageCache removeAllObjects];
}

当我尝试点击日志时,请说出来。

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(0x30afbe83 0x3ae5c6c7 0x30a31d95 0x638e9 0x3349d76f 0x3349d495 0x33406ea3 0x33406ea3 0x332781a1 0x332af9fd 0x332af3ab 0x33284d79 0x33283569 0x30ac6f1f 0x30ac63e7 0x30ac4bd7 0x30a2f471 0x30a2f253 0x357632eb 0x332e4845 0x628a5 0x3b355ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException

3 个答案:

答案 0 :(得分:0)

您的Trash数组不包含任何对象。 而您正试图从Trash数组

访问对象

NSString *trashBin = [Trash objectAtIndex:indexPath.row];

崩溃的原因是什么。

注意:对象名称应以小写字母开头。

答案 1 :(得分:0)

在您的代码中,Trash = [NSMutableArray array];将在某个时间自动释放,因此当您在' - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath'中访问它时,它已被释放。如果您确定有理由使用此变量而不是仅使用filenames,则可以在“ - (void)viewDidLoad”中执行此操作Trash = [[NSMutableArray array] retain];Trash = [[NSMutableArray alloc] init];

答案 2 :(得分:0)

目前尚不清楚你要做什么。 “垃圾箱”的概念表明您正在尝试实施两阶段删除:将项目放入垃圾箱,稍后再清空垃圾箱(当用户选择“清空垃圾箱”按钮时将其删除)。但是您的帖子和代码建议进行单阶段删除(用户选择删除而无法撤消)。

您的collectionView:didSelectItemAtIndexPath:委托方法看起来特别困惑。正如Bhumeshwer正确指出的那样,您的Trash为空并且尝试访问任何索引都会导致崩溃。在这段代码中你没有在Trash放置任何东西但是,通过简单地删除那行代码,我认为该方法不会做你想要的。

如果您要实施两阶段删除,我认为您只想删除filenames中的字符串并将其添加到Trash。请勿从Trash中删除该对象,也不要删除Trash中的文件。在其他地方(例如选择“清空垃圾箱”按钮时),请拨打deleteMyFiles清空垃圾箱。

如果要实现单阶段删除,请同时删除Trash:不要在viewDidLoad中分配它,也不要在didSelectItemAtIndexPath中清空它。简单地说,从文件名中删除对象并更新imageInCell!

建议:

  • 移动

    collectionTrash.delegate = self; collectionTrash.dataSource =自我;

到创建和初始化collectionTrash的位置。在viewDidLoad内部和for循环内部,它不在上下文中。混合不相关的代码行使您的代码无组织和混乱。至少,将其移出for循环。

  • 认为模型 - 视图 - 控制器。这里的模特是什么?是filenames还是Trash? CollectionView是filenames还是Trash的视图?什么是collectionTrash?

  • Trash应为trash(正如Bhumeshwer指出的那样);

  • 什么是NSString *myFileName;以及它在那做什么?

  • 不要忘记管理您的imageCache。你把图像放入,但不要把它们拿出来。从filenames删除文件后,从imageCache删除图片。

我可以继续,但会停在这里。祝你好运。