本文介绍了UIImage和NSCoding iOS 5.1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在iOS 5.1之前,如果你想在UIImage中使用NSCoding协议,你必须做这样的事情。

Prior to iOS 5.1 if you wanted to use NSCoding protocols with UIImage you had to do something like this.

@interface UIImage (NSCoding)

-(id)initWithCoder:(NSCoder *)deocder;
-(void)encodeWithCoder:(NSCoder *)encoder;

@end

然后自己实施。但是,对于iOS 5.1,这会在此协议的.M文件中生成警告类正在实现一个也将由其主类实现的方法。现在如果我删除这个扩展类iOS5.1会很高兴,但是这应该会在iOS4.0上崩溃和刻录。那么最好的行动方案是什么?

Then implement it yourself. However with iOS 5.1 this generates a warning "Category is implementing a method which will also be implemented by its primary class" in the .M file for this protocol. Now if I remove this extension class iOS5.1 will be happy, however this should crash and burn on iOS4.0. So what is the best course of action?

推荐答案

我有同样的问题,因为使用子类而不是cateogry为时已晚,我遵循zoul的建议使用class_addMethod,以下是我的实现:

I have the same issue, and since it is too late to use subclass rather than cateogry, I followed zoul's suggestion to use class_addMethod, and below is my implementation:

#import "UIImage-NSCoding.h"
#include <objc/runtime.h>
#define kEncodingKey        @"UIImage"

static void __attribute__((constructor)) initialize() {
    @autoreleasepool {

        if (![[UIImage class] conformsToProtocol:@protocol(NSCoding)]) {
            Class class = [UIImage class];

            if (!class_addMethod(
                                 class,
                                 @selector(initWithCoder:),
                                 class_getMethodImplementation(class, @selector(initWithCoderForArchiver:)),
                                 protocol_getMethodDescription(@protocol(NSCoding), @selector(initWithCoder:), YES, YES).types
                                )) {
                                    NSLog(@"Critical Error - [UIImage initWithCoder:] not defined.");
                                }

            if (!class_addMethod(
                                 class,
                                 @selector(encodeWithCoder:),
                                 class_getMethodImplementation(class, @selector(encodeWithCoderForArchiver:)),
                                 protocol_getMethodDescription(@protocol(NSCoding), @selector(encodeWithCoder:), YES, YES).types
                                )) {
                                    NSLog(@"Critical Error - [UIImage encodeWithCoder:] not defined.");
                                }

        }
    }
}

@implementation UIImage(NSCoding)

- (id) initWithCoderForArchiver:(NSCoder *)decoder {

    if ((self = [super init]))
    {
        NSData *data = [decoder decodeObjectForKey:kEncodingKey];
        self = [self initWithData:data];
    }

    return self;

}

- (void) encodeWithCoderForArchiver:(NSCoder *)encoder {

    NSData *data = UIImagePNGRepresentation(self);
    [encoder encodeObject:data forKey:kEncodingKey];

}

@end

希望它有所帮助!

[注意]

如果您使用此UIImage类别来存档 UIImageViewer 对象,请注意iOS 5中的 UIImageViewer 的NSCoding实现似乎已被破坏。保存和加载后,当在XIB中指定时,UIImageViewer的image属性会丢失(我还没有尝试在代码中创建UIImageViewer对象时是否存在相同的问题)。这已在iOS 6中修复。

If you use this UIImage category in order to archive UIImageViewer objects, beware that NSCoding implementation of UIImageViewer in iOS 5 seems to be broken. The image property of the UIImageViewer is lost after save and load, when it is specified in XIB (I have not tried to see if there is the same issue when UIImageViewer object is being created in code). This has been fixed in iOS 6.

[更新]

我已更改我的代码在+ load中添加方法而不是初始化(),它仍然只执行一次,但更早。我目前的实现:

I changed my code to add methods in +load instead initialize(), it is still being executed only once, but earlier. My current implementation:

#import "UIImage+NSCoding.h"
#import <objc/runtime.h>
#define kEncodingKey        @"UIImage"

@implementation UIImage (NSCoding)

+ (void) load
{

    @autoreleasepool {
        if (![UIImage conformsToProtocol:@protocol(NSCoding)]) {
            Class class = [UIImage class];
            if (!class_addMethod(
                                 class,
                                 @selector(initWithCoder:),
                                 class_getMethodImplementation(class, @selector(initWithCoderForArchiver:)),
                                 protocol_getMethodDescription(@protocol(NSCoding), @selector(initWithCoder:), YES, YES).types
                                 )) {
                NSLog(@"Critical Error - [UIImage initWithCoder:] not defined.");
            }

            if (!class_addMethod(
                                 class,
                                 @selector(encodeWithCoder:),
                                 class_getMethodImplementation(class, @selector(encodeWithCoderForArchiver:)),
                                 protocol_getMethodDescription(@protocol(NSCoding), @selector(encodeWithCoder:), YES, YES).types
                                 )) {
                NSLog(@"Critical Error - [UIImage encodeWithCoder:] not defined.");
            }

        }
    }
}

- (id) initWithCoderForArchiver:(NSCoder *)decoder {
    if (self = [super init]) {
        NSData *data = [decoder decodeObjectForKey:kEncodingKey];
        self = [self initWithData:data];
    }

    return self;

}

- (void) encodeWithCoderForArchiver:(NSCoder *)encoder {

    NSData *data = UIImagePNGRepresentation(self);
    [encoder encodeObject:data forKey:kEncodingKey];

}

@end

这篇关于UIImage和NSCoding iOS 5.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 14:14
查看更多