整个应用程序中的静态 UIImage
Posted
技术标签:
【中文标题】整个应用程序中的静态 UIImage【英文标题】:Static UIImage in whole application 【发布时间】:2011-11-30 13:06:20 【问题描述】:我想要一个静态 UIImage 以便我可以从不同的类访问它。我试过这种方法,但没有奏效:
制作了 Constans.h 文件:
static UIImage *myImage;
然后我在需要的地方导入这个标题。我认为此时 myImage 是静态的,对这个对象所做的任何更改都会随处可见。但看起来每个类都在处理它自己的 myImage 实例。有没有办法拥有这样的静态 UIImage?
编辑:
AppDelegate 中的属性工作正常。我现在有了静态 UIImage,但仍然没有达到预期的效果。
我在 ViewController 中有一个 UIImageView。我将图像加载到我的 delegate.myImage 之后:
delegate.myImage = [UIImage imageNamed:@"blah.png"];
myImageView.image = delegate.myImage;
图像已加载,但是我想在 AppDelegate 中更改它之后,但是当我以这种方式更改 myImage 时:
delegate.myImage = [UIImage imageNamed:@"blah2.png"];
myImageView 没有任何变化。就像 myImageView.image = delegate.myImage 复制了 myImage 的内存地址,所以如果我更改了 myImage 的引用,它不会影响 myImageView .图像。我想要一个 UIImage,在任何更改之后它也会影响 myImageView。
除了在 AppDelegate 中引用 myImageView 之外,还有其他方法吗?
【问题讨论】:
将其作为 appDelegate 类的属性。因为 appDelegate 类对象 inSelf 是静态副本。 【参考方案1】:与其制作一个明确的应用程序范围的图像,不如使用[UIImage imageNamed:]
。这会为您处理图像的缓存!无论您需要在哪里使用图像,只需像这样访问它:
[UIImage imageNamed:@"imageName.png"]
注意:这将导致内存中只有一个图像副本。您无法卸载它 - 但较新版本的 ios 可能会在内存不足的情况下在后台卸载它。
另请参阅[UIImage imageNamed:] 的 API 文档。
顺便说一句,imageNamed 通常用于多次使用的小图像——例如表格单元格图像 - 但如果您真的想要静态应用范围的图像,则没有理由不在大图像上使用它。
【讨论】:
【参考方案2】:关键字static
使变量在它定义的编译单元中成为本地变量。这意味着您可以安全地在多个 .c 文件中定义相同的符号;所有这些声明都不会冲突,每个文件都有自己的私有符号。
简单地说,如果你真的想定义一个可以被程序的任何部分访问的全局变量,你不需要static
关键字。但是,在这种情况下,“技巧”是在头文件中声明变量(您将其包含在全局应该可见的任何地方),如下所示:
extern UIImage *myImage;
然后在一个位置(.c 文件)中提供该变量的定义,而不使用 static
关键字。 extern
关键字告诉编译器该符号的定义不在当前编译单元(.c 文件)内,而是在另一个编译单元中。
现在,正如许多其他人指出的那样,您最好通过单例来做到这一点,尽管通常认为使用 singleton to mask a global variable is usually a way to mask a design problem。
【讨论】:
【参考方案3】:这是一个 C 问题(与 Objective-C 或 iOS 无关)
static
关键字使变量在其编译单元内具有粘性。
当您 #include
(或 ObjC 中的 #import
)一个标题时,就像它的内容被复制并粘贴到包含它的文件中一样。提醒一下,“.h”文件不会被编译(它们只是包含在自己编译的“.m”文件中)
因此,它的工作方式与您在 #include
的任何文件中键入 .h 中相同的代码行完全相同。
这解释了为什么在您的每个 #include "Constants.h"
源文件中,它们都会看到 myImage
变量的不同实例。
相反,您应该:
使用单例模式,专为此类情况设计 或者在实现文件(“Constants.m”)中使用 static 关键字,使这个变量在这个“Constants.m”文件的编译单元中具有粘性我强烈建议在这种情况下使用单例模式。 More info on Singleton Pattern here in the Apple official DevPedia
【讨论】:
【参考方案4】:你可以在你的应用委托中创建一个@property (nonatomic, retain) UIImage *image;
,在你想使用图像的每个类中你可以创建AppDelegate *delegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
,然后像这样从delegate
对象访问UIImage:
[imageView setImage:[delegate image]];
或者你可以使用这样的类:
头文件
@interface Data : NSObject
@property (nonatomic, strong) UIImage *image;
+ (Data *)sharedInstance;
+ (id)allocWithZone:(NSZone*)zone;
- (id)init;
- (id)copyWithZone:(NSZone *)zone;
@end
实现文件
@implementation Data
@synthesize image;
static Data *sharedInstance=nil;
+ (Data *)sharedInstance
if (sharedInstance == nil)
sharedInstance = [[super allocWithZone:NULL] init];
return sharedInstance;
+ (id)allocWithZone:(NSZone*)zone
return [self sharedInstance];
- (id)init
self = [super init];
if (self)
return self;
- (id)copyWithZone:(NSZone *)zone
return self;
@end
然后,你必须在你想要的每个类中导入Data.h
,然后使用:
UIImageView *imageView=[[UIImageView alloc] init];
[imageView setImage:[[Data sharedInstance] image]];
这对我很有用:)
【讨论】:
【参考方案5】:使用单例模式。
如果您的代码是 ARC,请点击此链接 http://lukeredpath.co.uk/blog/a-note-on-objective-c-singletons.html
【讨论】:
【参考方案6】:在 iPhone 中,AppDelegate 类充当静态类。这样您就可以在 YourAppDelegate 类的 Constant.h 中执行相同的操作。但不要使用静态关键字。
我不太确定,但认为它会起作用。 :)
【讨论】:
【参考方案7】:您可以使用 UIImage 类别作为示例来获取此图片。
在您的 .h 文件中添加您的静态方法。
#import <UIKit/UIKit.h>
@interface UIImage (StaticImage)
+(UIImage *)staticImage;
@end
并在您的 .m 文件中执行以下步骤:
#import "UIImage+StaticImage.h"
//This is your static image
static UIImage *myStaticImage;
@implementation UIImage (StaticImage)
+(void)initialize
//Important to add this condition, because this method will be called for every
//child class of UIImage class
if (self == [UIImage class])
myStaticImage = [[UIImage alloc] init];
+(UIImage *)staticImage
//Just return your existing static image
return myStaticImage;
@end
【讨论】:
以上是关于整个应用程序中的静态 UIImage的主要内容,如果未能解决你的问题,请参考以下文章