1

I want to have an static UIImage so I could access it from different classes. I've tried this way, but didn't worked:

Made Constans.h file with:

static UIImage *myImage;

And after that I import this header where it's needed. I thought that at this moment myImage was static and any changes made on this object would be visible everywhere. But it looks like every class is working on it's own myImage instance. Is there any way to have such static UIImage?


Edit:

Property in AppDelegate works fine. I have now static UIImage, but still I don't have effect I was expecting.

I have an UIImageView in ViewController. I load an image to my delegate.myImage and after I do:

delegate.myImage = [UIImage imageNamed:@"blah.png"];
myImageView.image = delegate.myImage;

Image is loaded, but after I want to change it in AppDelegate, but when I change myImage this way:

delegate.myImage = [UIImage imageNamed:@"blah2.png"];

nothing change in myImageView. It's like myImageView.image = delegate.myImage copied memory address of myImage so after if I change reference of myImage it's not affecting myImageView.image. I wanted to have an UIImage that after any changes it would also affect myImageView.

Is there other way than having an reference to myImageView in AppDelegate?

user1073352
  • 43
  • 1
  • 4
  • Make it as property of appDelegate class. since appDelegate class object inSelf is static copy. – Ishu Nov 30 '11 at 13:09

7 Answers7

4

Rather than making an explicitly application-wide image, just use [UIImage imageNamed:]. This handles caching of the image for you! Whereever you need to use the image, just access it like so:

[UIImage imageNamed:@"imageName.png"]

Note: this will cause there to be a single copy of the image in memory. You can't unload it -- but newer versions of iOS may unload it behind the scenes upon low memory conditions.

See also the API docs for [UIImage imageNamed:].

Btw, imageNamed is often used for small images that get used multiple times -- e.g. table cell images -- but there's no reason to not use it on large images if you genuinely want a static app-wide image.

occulus
  • 16,959
  • 6
  • 53
  • 76
3

The keyword static makes a variable local to the compilation unit where it id defined. This means you can safely have the same symbol defined in multiple .c files; all those declarations will not collide and each file will have its own private symbol.

Put simply, if you really want to define a global variable that is accessed by any part of your program, you do not need the static keyword. In this case, though, the "trick" is declaring the variable in a header file (that you include everywhere the global should be visible) like this:

 extern UIImage *myImage;

and then provide a definition for that variable in one single place (.c file) without the static keyword. The extern keyword tells the compiler that the definition for that symbol is not found inside of the current compilation unit (.c file), but in a different one.

Now, as many others have pointed out, you could better do that by means of a singleton, although it is usually recognized that using a singleton to mask a global variable is usually a way to mask a design problem.

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
1

That's a C problem (not specifically related to Objective-C or iOS)

The static keyword make the variable sticky inside its compilation unit.

When you #include (or #import in ObjC) a header, that's like if its content were copied & pasted into the file that includes it. As a reminder, ".h" files are not compiled (they are just included in ".m" files that themselves compile)

So that works exactly the same way as if you were typing the same lines of code you have in your .h in any file that #include it.

This explains why in each of your source files that #include "Constants.h" they each see a different instance of the myImage variable.


Instead you should:

  • Use the Singleton Pattern, that is specifically made for such cases
  • Or use the static keyword in an implementation file ("Constants.m") to make this variable sticky inside the compilation unit of this "Constants.m" file

I highly recommand to go with the Singleton Pattern for such cases anyway. More info on Singleton Pattern here in the Apple official DevPedia

AliSoftware
  • 32,623
  • 6
  • 82
  • 77
1

You can create a @property (nonatomic, retain) UIImage *image; in your app delegate and in every class you want to use the image you can create AppDelegate *delegate=(AppDelegate *)[[UIApplication sharedApplication] delegate]; and then access to the UIImage from the delegate object like this :

[imageView setImage:[delegate image]];

Or you can use a class like this :

header file

@interface Data : NSObject

@property (nonatomic, strong) UIImage *image;

+ (Data *)sharedInstance;
+ (id)allocWithZone:(NSZone*)zone;
- (id)init;
- (id)copyWithZone:(NSZone *)zone;

@end

implementation file

@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

Then, you have to import Data.h in every class you want and then use :

UIImageView *imageView=[[UIImageView alloc] init];
[imageView setImage:[[Data sharedInstance] image]];

This works great for me :)

Andrea Mario Lufino
  • 7,921
  • 12
  • 47
  • 78
0

Use the singleton pattern.

If your code is ARC follow this link http://lukeredpath.co.uk/blog/a-note-on-objective-c-singletons.html

Mathieu Hausherr
  • 3,485
  • 23
  • 30
0

In iPhone the AppDelegate class Acts a Static Class. so you can do the same thing which you have done in Constant.h in the YourAppDelegate Class. But dont use Static Keyword.

I am not very Sure but thinks it will work. :)

mAc
  • 2,434
  • 2
  • 22
  • 39
0

You can use UIImage category as example to get this picture.

In your .h file just add your static method.

#import <UIKit/UIKit.h>

@interface UIImage (StaticImage)

+(UIImage *)staticImage;

@end

And in your .m file do following steps:

#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
Gloomcore
  • 940
  • 7
  • 11