整个应用程序中的静态 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的主要内容,如果未能解决你的问题,请参考以下文章

在 UIImage 上突出显示(覆盖)特定区域

静态变量

static静态变量的理解

static静态变量的理解

为所有设备自动布局 UIImage

如何在 Swift 中截取 UITableView 中选定行的屏幕截图并将其保存为 UIImage?