IOS深度拷贝,NSArray,NSDictionary的分类(Category)

深度拷贝和浅拷贝的区别就自己找个地方看下。。。。。。。最下面贴上了NSArray和NSDictionary的深度拷贝分类方法

代码中常用的调试需要用的代码:这样日志只会在调试时候打印,发布的时候并不会出现

#ifdef DEBUG
#ifndef DLog
#   define DLog(fmt, ...) {NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);}
#endif
#ifndef ELog
#   define ELog(err) {if(err) DLog(@"%@", err)}
#endif
#else
#ifndef DLog
#   define DLog(...)
#endif
#ifndef ELog
#   define ELog(err)
#endif
#endif

下面这两段代码都是项目中拷贝出来的,所以特意备注一下。

SJDeepCopy.h文件

#import <Foundation/Foundation.h>

@interface NSArray (SJDeepCopy)

- (NSArray*)deepCopy;
- (NSMutableArray*) mutableDeepCopy;

@end

@interface NSDictionary (SJDeepCopy)

- (NSDictionary*)deepCopy;
- (NSMutableDictionary*)mutableDeepCopy;

@end

SJDeepCopy.m文件

#import "SJDeepCopy.h"

@implementation NSArray (SJDeepCopy)

- (NSArray*)deepCopy {
    NSUInteger count = [self count];
    id cArray[count];

    for (NSUInteger i = 0; i < count; ++i) {
        id obj = [self objectAtIndex:i];
        if ([obj respondsToSelector:@selector(deepCopy)]) {
            cArray[i] = [obj deepCopy];
        }
        else if ([obj respondsToSelector:@selector(copyWithZone:)]) {
            cArray[i] = [obj copy];
        }
        else {
            DLog(@"********Error:NSArray DeepCopy Failed!!! ********");
            return nil;
        }
    }

    NSArray *ret = [NSArray arrayWithObjects:cArray count:count];

    return ret;
}

- (NSMutableArray*)mutableDeepCopy {
    NSUInteger count = [self count];
    id cArray[count];

    for (NSUInteger i = 0; i < count; ++i) {
        id obj = [self objectAtIndex:i];

        // Try to do a deep mutable copy, if this object supports it
        if ([obj respondsToSelector:@selector(mutableDeepCopy)]) {
            cArray[i] = [obj mutableDeepCopy];
        }
        // Then try a shallow mutable copy, if the object supports that
        else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)]) {
            cArray[i] = [obj mutableCopy];
        }
        else if ([obj respondsToSelector:@selector(copyWithZone:)]) {
            cArray[i] = [obj copy];
        }
        else {
            DLog(@"********Error:NSArray MutableDeepCopy Failed!!! ********");
            return nil;
        }
    }

    NSMutableArray *ret = [NSMutableArray arrayWithObjects:cArray count:count];

    return ret;
}

@end

@implementation NSDictionary (SJDeepCopy)

- (NSDictionary*)deepCopy {
    NSUInteger count = [self count];
    id cObjects[count];
    id cKeys[count];

    NSEnumerator *e = [self keyEnumerator];
    NSUInteger i = 0;
    id thisKey;
    while ((thisKey = [e nextObject]) != nil) {
        id obj = [self objectForKey:thisKey];

        if ([obj respondsToSelector:@selector(deepCopy)]) {
            cObjects[i] = [obj deepCopy];
        }
        else if([obj respondsToSelector:@selector(copyWithZone:)]) {
            cObjects[i] = [obj copy];
        }
        else {
            DLog(@"********Error:NSDictionary DeepCopy Failed!!! ********")
            return nil;
        }

        if ([thisKey respondsToSelector:@selector(deepCopy)]) {
            cKeys[i] = [thisKey deepCopy];
        }
        else if ([thisKey respondsToSelector:@selector(copyWithZone:)]) {
            cKeys[i] = [thisKey copy];
        }
        else {
            DLog(@"********Error:NSDictionary Key DeepCopy Failed!!! ********")
            return nil;
        }

        ++i;
    }

    NSDictionary *ret = [NSDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count];

    return ret;
}

- (NSMutableDictionary*)mutableDeepCopy {
    unsigned int count = [self count];
    id cObjects[count];
    id cKeys[count];

    NSEnumerator *e = [self keyEnumerator];
    unsigned int i = 0;
    id thisKey;
    while ((thisKey = [e nextObject]) != nil) {
        id obj = [self objectForKey:thisKey];

        // Try to do a deep mutable copy, if this object supports it
        if ([obj respondsToSelector:@selector(mutableDeepCopy)]) {
            cObjects[i] = [obj mutableDeepCopy];
        }
        // Then try a shallow mutable copy, if the object supports that
        else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)]) {
            cObjects[i] = [obj mutableCopy];
        }
        else if ([obj respondsToSelector:@selector(copyWithZone:)]) {
            cObjects[i] = [obj copy];
        }
        else {
            DLog(@"********Error:NSDictionary MutableDeepCopy Failed!!! ********")
            return nil;
        }

        // I don't think mutable keys make much sense, so just do an ordinary copy
        if ([thisKey respondsToSelector:@selector(deepCopy)]) {
            cKeys[i] = [thisKey deepCopy];
        }
        else if([thisKey respondsToSelector:@selector(copyWithZone:)]) {
            cKeys[i] = [thisKey copy];
        }
        else {
            return nil;
        }

        ++i;
    }

    NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count];

    return ret;
}

@end
时间: 2024-08-05 15:45:11

IOS深度拷贝,NSArray,NSDictionary的分类(Category)的相关文章

ios model字典 NSArray NSDictionary小结

ios model字典 #import <Foundation/Foundation.h> @interface AdObject : NSObject /// 广告ID @property (strong,nonatomic) NSString *adID; /// 广告图片的地址 @property (strong,nonatomic) NSString *imagePath; /// 广告标题 @property (strong,nonatomic) NSString *adTitle;

oc/object-c/ios哪种遍历NSArray/NSDictionary方式快?测试报告

做app的时候,总免不了要多次遍历数组或者字典.究竟哪种遍历方式比较快呢?我做了如下测试:首先定义测试用宏: ? 1 2 3 4 5 6 7 8 9 #define MULogTimeintervalBegin(INFO) NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];\ NSTimeInterval duration = 0;\ NSLog(@"MULogTimeintervalBegin:%@", IN

关于ios object-c 类别-分类 category 的静态方法与私有变量,协议 protocol

关于ios object-c 类别-分类 category 的静态方法与私有变量,协议 protocol 2014-02-18 19:57 315人阅读 评论(0) 收藏 举报 1.category,覆盖原类的方法,即使不引用该category头文件,也能覆盖,respondsToSelector:方法也能响应.2.category,不可以有私有变量,但是可以有@property的声明,property的声明只是声明了该类的set,get方法(需要引用该category的头文件),但是categ

[转]一些NSArray,NSDictionary,NSSet相关的算法知识

iOS编程当中的几个集合类:NSArray,NSDictionary,NSSet以及对应的Mutable版本,应该所有人都用过.只是简单使用的话,相信没人会用错,但要做到高效(时间复杂度)精确(业务准确性),还需要了解其中所隐藏的算法知识. 在项目当中使用集合类几乎是不可避免的,集合类的使用场景其实可以进行抽象的归类.大多数时候我们需要将若干个对象(object)暂时保存起来,以备后续的业务逻辑进行操作,「保存和操作」,或者说「存与取」,对应到计算机世界的术语就是读和写.最初保存的时候我们Ins

黑马程序员---OC基础7【ARC概念】【ARC对象内存管理】【分类Category】

------- iOS培训.Android培训.Java培训.期待与您交流! ---------- [ARC概念]   1.指针的分类 1)强指针,默认的情况下,所有的指针都是强指针,关键字strong: 2)弱指针,_ _weak关键字修饰符的指针 2.ARC概念 自动引用计数 永远不要写retain和release.autorelease三个关键字 编译器会在编译的时候自动插入retain和release.autorelease, 是一个编译器的特性:“垃圾回收”是运行时的特性 3.ARC工

iOS深度学习 - Runtime

这里是iOS深度学习-Runtime的大纲. 一.Class 1,isa指针.super_class指针 2,metaclass(元类) 3,objc_object(表示一个 类的实例 的结构体) 和  id类型(typedef struct objc_object *id) 二.Ivar objc_setAssociatedObject 三.Method cache机制.SEL.IMP指针.Method Swizzling 四.Protocal objc_protocol_list 五.Cat

Objective-C 分类Category

OC提供了一种可以在不修改类的源码基础上,扩展类的方法的功能,"分类"Category,这个机制和C#中的扩展方法类似,一般用于在不方便修改类的源码时(如OC系统相关的类库),但有有需求要拓展类的方法,可以使用分类来实现. Java中应该是没有提供相关的机制,但是Java可以通过动态代理来实现AOP,在切入点前后执行代码逻辑,个人认为比OC还要方便. // // Girl.h // 10_Category // // Created by apple on 14/12/23. // C

Objective-C分类 (category)和扩展(Extension)

1.分类(category) 使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以做到,这点和javascript中使用原型来定义属性有点类似. 我们可以为一个类创建一个新的方法,而不需要在代码中编辑类定义. 下面就是定义并使用分类的例子程序,通过下面代码,我们可以给Object-C中的NSString 添加camelCaseString分类,使用camelCaseString方

NSArray / NSDictionary 转 Json

在iOS开发中,网络数据转换是必不可少的,我们时常会用到NSArray / NSDictionary转化成Json字符串. 网上看到很多都是借助于第三方去转化,就个人而言,我认为三方的东西一方面增加了冗余度,另一方面时常更新,比较头疼. 仔细看看了苹果自带的json序列化解析器,苹果提供了字典和数组转化Json字符串的方法. NSDictionary * dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"张三",@"na