首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么NSMutableDictionary的setObjectForKey方法会导致崩溃?

为什么NSMutableDictionary的setObjectForKey方法会导致崩溃?
EN

Stack Overflow用户
提问于 2017-02-07 13:55:24
回答 1查看 78关注 0票数 0

在NSMutableDictionary对象上调用setObjectForKey方法时,应用程序崩溃。isUrlSavedWithThumbDic和url字符串具有控制台中显示的值。

代码语言:javascript
运行
复制
[isUrlSavedWithThumbDic setObject:[NSNumber numberWithBool:YES] forKey:url];

代码在UIImageView类别中运行。isURLSavedWithThumbDic是类别中的静态变量,声明为:

代码语言:javascript
运行
复制
static NSMutableDictionary *isUrlSavedWithThumbDic;

在category方法中初始化isURlSavedWithThumbDic,然后在其上设置任何值。

代码语言:javascript
运行
复制
if (isUrlSavedWithThumbDic == NULL || isUrlSavedWithThumbDic == nil){
     isUrlSavedWithThumbDic = [NSMutableDictionary new];
}

崩溃不会每次都来,应用程序运行时大多没有问题。在类别中声明静态变量有什么逻辑问题吗?

UIImageView分类方法的完整源代码:

代码语言:javascript
运行
复制
-(void)SetThumbImageForDownloadURL:(NSString*)url  indexPath:(NSIndexPath*)indexPath  waterMarkData:(CLWaterMarkModel*)watermarkData genericUrl:(NSString*)genericUrl placeHolder:(NSString*)placeHolder WillHaveWaterMark:(BOOL)willHaveWaterMark{


    __weak __typeof__(self) weakSelf = self;
    [self setImage:nil];
    if([url isEqualToString:@""]  || ![url caseInsensitiveCompare:@"unknown"] ) {
        [self  setImage:[UIImage imageNamed:placeHolder]];
    }
    else
    {
        NSData *imageData = [CMCache getThumbImageForKey:[url MD5] withPath:CacheDir];
        if(imageData)
        {
             UIImage *image = [UIImage imageWithData:imageData];
            if(!willHaveWaterMark){
                //my projects
                 [self  setImage:image];
            }else{
                if(watermarkData == nil){
                    //don't show image if watermark data is not there. Every thumb Image should have watermark data
                   // [self  setImage:image];

                }else{
                    if (isUrlSavedWithThumbDic == NULL || isUrlSavedWithThumbDic == nil){
                        isUrlSavedWithThumbDic = [NSMutableDictionary new];
                    }@try {
                        BOOL isSavedWithThumb = [[isUrlSavedWithThumbDic objectForKey:url] boolValue];
                        if( isSavedWithThumb){
                            [self  setImage:image];
                        }else{
                            //save image with thumb this time
                            image = [UIImage renderWaterMarkImage:image withModel:watermarkData generic:genericUrl];
                            [self  setImage:image];
                            [CMCache saveThumbnailImageAndCompressIfRequired:UIImagePNGRepresentation(image) forKey:[url MD5] withNewPath:CacheDir size:self.frame.size] ;

                            [isUrlSavedWithThumbDic setObject:[NSNumber numberWithBool:YES] forKey:url];

                        }

                    } @catch (NSException *exception) {
                        DLog(@"Exception:%@",exception);

                    }
                }
            }


        }
        else
        {

            if(downloadInProgress == nil){
                downloadInProgress = [NSMutableDictionary new];
                isUrlSavedWithThumbDic = [NSMutableDictionary new];
            }

            if (downloadInProgress[url] == nil ){
                downloadInProgress[url] = url;

                [CMRestInterface asyncImageDownload:url withProgressHandler:nil andCompletionHandler:^(UIImage *image, NSUInteger errorCode)
                 {
                     [downloadInProgress removeObjectForKey:url];

                     __typeof__(self) strongSelf = weakSelf;
                     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

                         if (image)
                         {
                             @try {
                             //
                                 UIImage *customImage = image;
                                 if(watermarkData != nil){
                                     customImage = [UIImage renderWaterMarkImage:image withModel:watermarkData generic:genericUrl];

                                     [isUrlSavedWithThumbDic setObject:[NSNumber numberWithBool:YES] forKey:url];

                                 } else {
                                     [isUrlSavedWithThumbDic setObject:[NSNumber numberWithBool:NO] forKey:url];
                                 }
                                 [CMCache saveThumbnailImageAndCompressIfRequired:UIImagePNGRepresentation(customImage) forKey:[url MD5] withNewPath:CacheDir size:self.frame.size] ;
                                 dispatch_async(dispatch_get_main_queue(), ^{

                                UIView *parentView = strongSelf.superview;
                                while(parentView != nil && ![parentView isKindOfClass:NSClassFromString(@"UICollectionView")]
                                      && ![parentView isKindOfClass:NSClassFromString(@"UITableView")]){

                                    parentView = parentView.superview;

                                }
                                //ImageViewInsideTAbleViewCell
                                if(parentView == nil){
                                    if(willHaveWaterMark){
                                        if(watermarkData){
                                            if(!customImage){
                                                [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                            }else{
                                                [strongSelf setImage:customImage];
                                            }
                                        }else{
                                            //[ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                        }

                                    }else{
                                        if(!customImage){
                                            [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                        }else{
                                            [strongSelf setImage:customImage];
                                        }
                                    }

                                } else if([parentView isKindOfClass:NSClassFromString(@"UICollectionView")]){
                                    UICollectionView *cv = (UICollectionView*)parentView;


                                    UICollectionViewCell *cell = [cv cellForItemAtIndexPath:indexPath];
                                    if(cell){
                                        if(willHaveWaterMark){
                                            if(watermarkData){
                                                if(!customImage){
                                                    [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                                }else{
                                                    [strongSelf setImage:customImage];
                                                }
                                            }else{
                                                // [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                            }

                                        }else{
                                            if(!customImage){
                                                [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                            }else{
                                                [strongSelf setImage:customImage];
                                            }
                                        }

                                    }



                                } else if ([parentView isKindOfClass:NSClassFromString(@"UITableView")]){
                                    UITableView *tv  = (UITableView*)parentView;

                                    //  [tv reloadRowsAtIndexPaths:[tv indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
                                    UITableViewCell *cell = [tv cellForRowAtIndexPath:indexPath];
                                    if(cell){
                                        if(willHaveWaterMark){
                                            if(watermarkData){
                                                if(!customImage){
                                                    [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                                }else{
                                                    [strongSelf setImage:customImage];
                                                }
                                            }else{
                                                //  [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                            }

                                        }else{
                                            if(!customImage){
                                                [ strongSelf setImage:[UIImage imageNamed:placeHolder]];
                                            }else{
                                                [strongSelf setImage:customImage];
                                            }
                                        }

                                    }

                                }


                            });
                            }@catch (NSException *exception) {
                                 DLog(@"Exception:%@",exception);
                             }

                         }else{
                             dispatch_async(dispatch_get_main_queue(), ^{
                                [strongSelf setImage:[UIImage imageNamed:placeHolder]];
                             });

                         }

                    });


                }];

            }

        }

    }



}
EN

回答 1

Stack Overflow用户

发布于 2018-06-07 17:28:38

我找到了crash背后的原因。这个问题是一个并发问题。多个线程并行运行,其中每个线程都试图下载一个图像,下载成功后,它将更新可变字典。当两个单独的线程试图在字典中同时写入时,应用程序会崩溃,因为代码不是线程安全的。一种快速的解决方法是在串行队列中移动共享资源,这样所有线程都可以一次一个地写入字典。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42082716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档