Статический UIImage во всем приложении - PullRequest
1 голос
/ 30 ноября 2011

Я хочу иметь статический UIImage, чтобы я мог получить к нему доступ из разных классов.Я пробовал таким образом, но не сработало:

Сделано Constans.h файл с:

static UIImage *myImage;

И после этого я импортирую этот заголовок, где оннеобходимо.Я думал, что в этот момент myImage был статичным, и любые изменения, сделанные в этом объекте, будут видны везде.Но похоже, что каждый класс работает над своим собственным myImage экземпляром.Есть ли способ получить такой статический UIImage?


Редактировать:

Свойство в AppDelegate работает нормально.У меня теперь есть статический UIImage, но все равно я не получил ожидаемого эффекта.

У меня есть UIImageView в ViewController.Я загружаю изображение в свой 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.image .Я хотел получить UIImage, который после любых изменений также влиял бы на myImageView .

Есть ли другой способ, кроме ссылки на myImageView в AppDelegate?

Ответы [ 7 ]

4 голосов
/ 30 ноября 2011

Вместо того, чтобы делать явное изображение для всего приложения, просто используйте [UIImage imageNamed:].Это обрабатывает кэширование изображения для вас!Где бы вам ни понадобилось использовать изображение, просто получите к нему доступ следующим образом:

[UIImage imageNamed:@"imageName.png"]

Примечание: это приведет к тому, что в памяти останется одна копия изображения.Вы не можете выгрузить его, но более новые версии iOS могут выгружать его за кулисами при нехватке памяти.

См. Также документы API для [UIImage imageNamed:] .

Кстати, imageNamed часто используется для небольших изображений, которые используются несколько раз - например, для изображений ячейки таблицы - но нет причин не использовать его на больших изображениях, если вы действительно хотите статическое изображение для всего приложения.

3 голосов
/ 30 ноября 2011

Ключевое слово static делает переменную локальной для единицы компиляции, в которой он определен. Это означает, что вы можете безопасно иметь один и тот же символ, определенный в нескольких файлах .c; все эти объявления не будут конфликтовать, и каждый файл будет иметь свой собственный закрытый символ.

Проще говоря, если вы действительно хотите определить глобальную переменную, к которой обращается какая-либо часть вашей программы, вам не нужно ключевое слово static. В этом случае, однако, «трюк» объявляет переменную в заголовочном файле (который вы включаете везде, где должно быть видно глобальное значение) следующим образом:

 extern UIImage *myImage;

и затем укажите определение этой переменной в одном месте (файл .c) без ключевого слова static. Ключевое слово extern сообщает компилятору, что определение этого символа находится не внутри текущей единицы компиляции (файл .c), а в другом.

Теперь, как отмечали многие другие, лучше сделать это с помощью синглтона, хотя обычно признается, что использование синглтона для маскирования глобальной переменной обычно является способом маскировки проблемы проектирования .

1 голос
/ 30 ноября 2011

Вы можете создать @property (nonatomic, retain) UIImage *image; в своем делегате приложения и в каждом классе, в котором вы хотите использовать изображение, которое вы можете создать AppDelegate *delegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];, а затем получить доступ к UIImage из объекта delegate, например:

[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]];

Это прекрасно работает для меня:)

1 голос
/ 30 ноября 2011

Это проблема C (не относящаяся конкретно к Objective-C или iOS)

Ключевое слово static делает переменную закрепленной внутри блока компиляции.

Когда вы #include (или #import в ObjC) заголовок, как если бы его содержимое было скопировано и вставлено в файл, который его включает.Напоминаем, что файлы ".h" не компилируются (они просто включаются в файлы ".m", которые сами компилируются)

Так что это работает точно так же, как если бы вы печатали те же строки кодау вас есть .h в любом файле, который #include it.

Это объясняет, почему в каждом из ваших исходных файлов #include "Constants.h" каждый из них видит отдельный экземпляр переменной myImage.


Вместо этого вы должны:

  • Использовать шаблон Singleton , который специально создан для таких случаев
  • Или использовать ключевое слово static вфайл реализации ("Constants.m"), чтобы сделать эту переменную закрепленной внутри модуля компиляции этого файла "Constants.m"

Я настоятельно рекомендую использовать шаблон Singleton для таких случаевв любом случае . Более подробная информация о Singleton Pattern здесь, в официальном DevPedia Apple

0 голосов
/ 30 ноября 2011

Вы можете использовать категорию 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
0 голосов
/ 30 ноября 2011

В iPhone класс AppDelegate действует как статический класс.так что вы можете сделать то же самое, что вы сделали в Constant.h в классе YourAppDelegate .Но не используйте статическое ключевое слово.

Я не очень уверен, но думаю, что это будет работать.:)

0 голосов
/ 30 ноября 2011

Используйте шаблон синглтона.

Если ваш код ARC, перейдите по этой ссылке http://lukeredpath.co.uk/blog/a-note-on-objective-c-singletons.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...