Ios 如何检查是否设置了NSCache实例值
我有一个Ios 如何检查是否设置了NSCache实例值,ios,objective-c,nscache,Ios,Objective C,Nscache,我有一个NSCache的实例,比如:NSCache*imageCache它基本上用于保存一些具有不同“@keys”的远程“图像”值。开始时,我在全局类中设置一个alloc&initNSCache,并设置一个if-else条件,如下所示: if (self.imageCache == nil) { self.imageCache = [[NSCache alloc] init]; } else { NSLog(@"cache set"); } 我在所有的视图控制器中导入“全局类”
NSCache
的实例,比如:NSCache*imageCache
它基本上用于保存一些具有不同“@keys”
的远程“图像”值。开始时,我在全局类中设置一个alloc
&init
NSCache
,并设置一个if-else
条件,如下所示:
if (self.imageCache == nil)
{
self.imageCache = [[NSCache alloc] init];
}
else
{
NSLog(@"cache set");
}
我在所有的视图控制器中导入“全局类”,这样我就不必每次都解析图像了。但问题是当我每次转到其他ViewControllers
时,似乎都是NSCache
alloc
&init
。因为加载图像所需的时间与加载1stVC
所需的时间相同。我认为if-else
条件没有很好地工作,或者它不是检查NSCache
设置与否的合适方法。
谁能告诉我它有什么问题吗?还有一件事,imageCache
是从全局变量使用的。提前感谢。
祝你今天愉快 添加: 这是我在
UIScrollView
中将ui按钮加载为子视图的方法。这是一个UIViewClass
,我将其添加到我的“EveryViewController”中作为子视图
只需查看if(cachedImage)
行。它很好用。但是当我想检查NSCache
(iADImageCache)设置与否时,它会显示它没有设置。但这应该被设定。在这种情况下,如何使用不同的@“键”
名称检查所有iADImageCache
?
再次感谢
-(void) loadUIButton
{
[self loadScrollView];
for (int i = 0; i < [iADDisplayArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(i*320, 0, ButtonWidth, ButtonHight)];
currentAd = [iADDisplayArray objectAtIndex:i];
NSString *path = currentAd.bannerIconURL;
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *requestWithBodyParams = [NSMutableURLRequest requestWithURL:url];
NSData *imageData = [NSURLConnection sendSynchronousRequest:requestWithBodyParams returningResponse:nil error:nil];
UIImage *originalImage = [UIImage imageWithData:imageData];
UIImage *cachedImage = [self.iADImageCache objectForKey:currentAd.bannerIconURL];
if (cachedImage)
{
[adButtonOutLet setImage:cachedImage forState:UIControlStateNormal];
//NSLog(@"OnecachedImage %@", cachedImage);
}
else
{
[self.iADImageCache setObject:originalImage forKey:currentAd.bannerIconURL];
[adButtonOutLet setImage:originalImage forState:UIControlStateNormal];
NSLog(@"OneimageCache %@", self.iADImageCache);
}
adButtonOutLet.userInteractionEnabled= YES;
[adButtonOutLet setTag:i];
[adButtonOutLet addTarget:self action:@selector(goToURL:) forControlEvents:UIControlEventTouchUpInside];
[self.iADScrollView addSubview:adButtonOutLet];
}
}
-(无效)加载按钮
{
[自动加载滚动视图];
对于(int i=0;i<[iADDisplayArray count];i++)
{
adButtonOutLet=[[UIButton alloc]initWithFrame:CGRectMake(i*320,0,ButtonWidth,ButtonHight)];
currentAd=[iADDisplayArray objectAtIndex:i];
NSString*path=currentAd.bannerIconURL;
NSURL*url=[NSURL URLWithString:path];
NSMutableURLRequest*requestWithBodyParams=[NSMutableUrlRequestWithURL:url];
NSData*imageData=[NSURLConnection sendSynchronousRequest:requestWithBodyParams returningResponse:nil错误:nil];
UIImage*originalImage=[UIImage imageWithData:imageData];
UIImage*cachedImage=[self.iADImageCache objectForKey:currentAd.bannerIconURL];
if(缓存图像)
{
[AdButtonOutletSetImage:cachedImage for状态:UIControlStateNormal];
//NSLog(@“OnecachedImage%@”,cachedImage);
}
其他的
{
[self.iADImageCache setObject:originalImage forKey:currentAd.bannerIconURL];
[adButtonOutLet设置图像:状态的原始图像:uicontrol状态正常];
NSLog(@“OneimageCache%@”,self.iADImageCache);
}
adButtonOutLet.userInteractionEnabled=YES;
[AdButtonOutletSetTag:i];
[adButtonOutLet添加目标:自我操作:@selector(GoTour:)for ControlEvents:UIControlEventTouchUpInside];
[self.iADScrollView addSubview:adButtonOutLet];
}
}
您可以创建一个singleton类,应用程序中的实例已完成启动,并通过所有视图控制器在任何地方使用它。在singleton类中放置一个属性
@property(nonatomic,strong) NSCache* imageCache;
然后在singleton类init方法中只执行一次。这样,您就不必关心它,只需将图像添加到缓存中即可。当然,您必须根据缓存中是否存在密钥来检查图像是否缓存
NSCache* globalCache = [SingletonClass sharedInstanceMethod].imageCache;
UIImage *imageX = [globalCache objectForKey: @"keyX"];
if (!imageX) {
// download your image
imageX = <Download method>;
[globalCache setObject: imageX forKey: @"keyX"];
}
// Do your stuff (like showing the image)
....
...
..
.
NSCache*globalCache=[SingletonClass sharedInstanceMethod].imageCache;
UIImage*imageX=[globalCache objectForKey:@“keyX”];
如果(!imageX){
//下载你的图片
imageX=;
[globalCache setObject:imageX forKey:@“keyX”];
}
//做你的事情(比如展示图片)
....
...
..
.
希望它有帮助除非整个程序中确实需要,否则我建议另一种方法,通过添加class方法将缓存限制在实际需要使用它的类:
+ (NSCache *)staticCacheForClass
{
static NSCache *staticCache;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
staticCache = [NSCache new];
staticCache.name = @"myCache";
});
return staticCache;
}
使用此选项-将对缓存的更改限制在使用它的类的内部,并避免创建另一个单例。在创建和销毁此类实例的过程中也会保留缓存
也就是说,如果您需要从不同的类访问缓存,那么单例可能是一个可行的解决方案,因为缓存单例并不是真正的全局状态
干杯。laco,谢谢你的评论。我将在我的主要帖子中添加一些代码,以便您能够更多地了解情况。对不起,我不明白您为什么要检查iADImageCache
是否已设置。即使它为null,也意味着您将尝试调用非实例化对象的方法(因此,iADImageCache
的objectForKey:
方法),这将是一个无操作(无操作),并将返回null到cachedImage
对象。显然,不可能不设置iADImageCache
,但从中正确返回cachedImage
。(注:我建议将sendSynchronousRequest:
移动到else块中,以避免下载图像,即使您已经缓存了它)。@Luca laco,是的,这让我明白了这一点。移动sendSynchronousRequest:
在else
部分中,似乎不再每次下载图像了。:)好好待着,亲爱的。