当前位置:  编程技术>移动开发
本页文章导读:
    ▪[039] 微信大众帐号开发教程第15篇-自定义菜单的view类型(访问网页)        [039] 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)引言及内容概要 距离写上一篇文章《自定义菜单的创建及菜单事件响应》整整过了两个月的时间,那时公众平台还没有开.........
    ▪ Mac 10.7.装配XCode3.2.6的方法        Mac 10.7.*安装XCode3.2.6的方法1、首先,在Xcode 3.2.6的磁盘映像(dmg文件)上点击右键,选择“磁盘工具”打开,如图1所示,转换成一个可读写的dmg文件,如图2所示。 图1 图2 转换好后双击它.........
    ▪ 浅析Objective-C 轻重缓急拷贝       浅析Objective-C 深浅拷贝 先了解下概念: 浅 复 制:在复制操作时,对于被复制的对象的每一层复制都是指针复制。 深 复 制:在复制操作时,对于被复制的对象至少有一层复制是对象复制.........

[1][039] 微信大众帐号开发教程第15篇-自定义菜单的view类型(访问网页)
    来源: 互联网  发布时间: 2014-02-18
[039] 微信公众帐号开发教程第15篇-自定义菜单的view类型(访问网页)

引言及内容概要

距离写上一篇文章《自定义菜单的创建及菜单事件响应》整整过了两个月的时间,那时公众平台还没有开放view类型的菜单。在不久前,微信公众平台悄悄开放了view类型的菜单,却没有在首页发布任何通知,貌似微信团队很喜欢这么干。一个偶然的机会,我留意到API文档的自定义菜单接口发生了变化,增加了对菜单view类型的说明:

view(访问网页):

 用户点击view类型按钮后,会直接跳转到开发者指定的url中。

于是我在第一时间更新了小q机器人(微信号:xiaoqrobot)的菜单,在一级菜单“更多”下增加了二级菜单“使用帮助”,点击该菜单项会直接跳转到网页,如下图所示。


最近也有不少网友问起这种类型的菜单是如何创建的,本篇文章就为大家介绍下view类型的自定义菜单该如何创建。


自定义菜单的两种类型(click和view)

公众平台API文档中给出了自定义菜单的json结构示例,我从中截取两个菜单项的json代码,一个是click类型,另一个是view类型,如下所示。

{	
	"type":"click",
	"name":"今日歌曲",
	"key":"V1001_TODAY_MUSIC"
},
{
	"type":"view",
	"name":"歌手简介",
	"url":"http://www.qq.com/"
}
从上面可以看出,两种类型的菜单除了type值不同之外,属性也有差别。click类型的菜单有key属性,而view类型的菜单没有key属性,与之对应的是url属性。通过上一篇的学习我们知道,key值是用于判断用户点击了哪个click类型的菜单项。而view类型的菜单没有key属性,目前无法在公众账号后台判断是否有用户点击了view类型的菜单项,也就没办法知道哪个用户点击了view类型的菜单项。


建立view类型的菜单对象

View类型的菜单有3个属性:type、name和url。在上一篇文章中,我们创建了菜单项的基类Button,Button类只有一个属性name。View类型的菜单对象也需要继承Button类,代码如下:

package org.liufeng.weixin.pojo;

/**
 * view类型的菜单
 * 
 * @author liuyq
 * @date 2013-04-10
 */
public class ViewButton extends Button {
	private String type;
	private String url;

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(/blog_article/String url/index.html) {
		this.url = url;
	}
}


创建带view类型的菜单示例

我们对前一篇文章中给出的菜单创建代码进行调整,增加view类型的菜单项,完整的菜单创建代码如下:

package org.liufeng.weixin.main;

import org.liufeng.weixin.pojo.AccessToken;
import org.liufeng.weixin.pojo.Button;
import org.liufeng.weixin.pojo.CommonButton;
import org.liufeng.weixin.pojo.ComplexButton;
import org.liufeng.weixin.pojo.Menu;
import org.liufeng.weixin.pojo.ViewButton;
import org.liufeng.weixin.util.WeixinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 菜单管理器类
 * 
 * @author liufeng
 * @date 2013-08-08
 */
public class MenuManager {
	private static Logger log = LoggerFactory.getLogger(MenuManager.class);

	public static void main(String[] args) {
		// 第三方用户唯一凭证
		String appId = "000000000000000000";
		// 第三方用户唯一凭证密钥
		String appSecret = "00000000000000000000000000000000";

		// 调用接口获取access_token
		AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);

		if (null != at) {
			// 调用接口创建菜单
			int result = WeixinUtil.createMenu(getMenu(), at.getToken());

			// 判断菜单创建结果
			if (0 == result)
				log.info("菜单创建成功!");
			else
				log.info("菜单创建失败,错误码:" + result);
		}
	}

	/**
	 * 组装菜单数据
	 * 
	 * @return
	 */
	private static Menu getMenu() {
		CommonButton btn11 = new CommonButton();
		btn11.setName("天气预报");
		btn11.setType("click");
		btn11.setKey("11");

		CommonButton btn12 = new CommonButton();
		btn12.setName("公交查询");
		btn12.setType("click");
		btn12.setKey("12");

		CommonButton btn13 = new CommonButton();
		btn13.setName("周边搜索");
		btn13.setType("click");
		btn13.setKey("13");

		CommonButton btn14 = new CommonButton();
		btn14.setName("历史上的今天");
		btn14.setType("click");
		btn14.setKey("14");
		
		CommonButton btn15 = new CommonButton();
		btn15.setName("电影排行榜");
		btn15.setType("click");
		btn15.setKey("32");

		CommonButton btn21 = new CommonButton();
		btn21.setName("歌曲点播");
		btn21.setType("click");
		btn21.setKey("21");

		CommonButton btn22 = new CommonButton();
		btn22.setName("经典游戏");
		btn22.setType("click");
		btn22.setKey("22");

		CommonButton btn23 = new CommonButton();
		btn23.setName("美女电台");
		btn23.setType("click");
		btn23.setKey("23");

		CommonButton btn24 = new CommonButton();
		btn24.setName("人脸识别");
		btn24.setType("click");
		btn24.setKey("24");

		CommonButton btn25 = new CommonButton();
		btn25.setName("聊天唠嗑");
		btn25.setType("click");
		btn25.setKey("25");

		CommonButton btn31 = new CommonButton();
		btn31.setName("Q友圈");
		btn31.setType("click");
		btn31.setKey("31");

		CommonButton btn33 = new CommonButton();
		btn33.setName("幽默笑话");
		btn33.setType("click");
		btn33.setKey("33");
		
		CommonButton btn34 = new CommonButton();
		btn34.setName("用户反馈");
		btn34.setType("click");
		btn34.setKey("34");
		
		CommonButton btn35 = new CommonButton();
		btn35.setName("关于我们");
		btn35.setType("click");
		btn35.setKey("35");
		
		ViewButton btn32 = new ViewButton();
		btn32.setName("使用帮助");
		btn32.setType("view");
		btn32.setUrl("http://liufeng.gotoip2.com/xiaoqrobot/help.jsp");

		ComplexButton mainBtn1 = new ComplexButton();
		mainBtn1.setName("生活助手");
		mainBtn1.setSub_button(new Button[] { btn11, btn12, btn13, btn14, btn15 });

		ComplexButton mainBtn2 = new ComplexButton();
		mainBtn2.setName("休闲驿站");
		mainBtn2.setSub_button(new Button[] { btn21, btn22, btn23, btn24, btn25 });

		ComplexButton mainBtn3 = new ComplexButton();
		mainBtn3.setName("更多");
		mainBtn3.setSub_button(new Button[] { btn31, btn33, btn34, btn35, btn32 });

		/**
		 * 这是公众号xiaoqrobot目前的菜单结构,每个一级菜单都有二级菜单项<br>
		 * 
		 * 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?<br>
		 * 比如,第三个一级菜单项不是“更多体验”,而直接是“幽默笑话”,那么menu应该这样定义:<br>
		 * menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 });
		 */
		Menu menu = new Menu();
		menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 });

		return menu;
	}
}

119~122行代码就是用于创建view类型菜单项的。上面的菜单结构也是小q机器人(微信号:xiaoqrobot)目前在使用的,读者可以对照着理解。

补充:居然还有些网友问我上面的自定义菜单创建代码在哪里调用,问我为什么不把调用的代码也公开?搞的我都有点不好意思了。上面的菜单创建代码是写在main方法中,直接在开发工具中运行一下就可以了,这应该是最最基础的Java知识了。另外,菜单只要创建一次,会一直存在的,不需要每次启动应用程序都去创建菜单。当然,你也可以把菜单的创建代码集成到项目中,并非一定要放在main方法中。程序是死的,人是活的,解决方法往往有很多种,怎么方便实用就怎么来!


如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号xiaoqrobot来支持柳峰!

转帖请注明本文出自柳峰的博客(http://blog.csdn.net/lyq8479),请尊重他人的辛勤劳动成果,谢谢!


1楼xirilianren28453小时前此帖必火,果断占位留名!

    
[2] Mac 10.7.装配XCode3.2.6的方法
    来源: 互联网  发布时间: 2014-02-18
Mac 10.7.*安装XCode3.2.6的方法

1、首先,在Xcode 3.2.6的磁盘映像(dmg文件)上点击右键,选择“磁盘工具”打开,如图1所示,转换成一个可读写的dmg文件,如图2所示。


图1


图2

转换好后双击它,让它在Finder里面显示,并点击右键Xcode包(Xcode and iOS SDK),选择“显示包内容”进入Contents文件夹,如图3所示。


图3

2、用”文本编辑器“打开iPhoneSDKSL.dist文件,点击command+F 搜索“10.7“,并用”10.8“替换它保存再运行这个安装包。

3、 安装过程种可能会出现提示要关闭“iTunes”的情况,解决方法: 应用程序-实用工具-活动监视器,找到iTunesHelper进程杀掉即可。

4、最后值得注意的是,我在Mac 10.8.*上用同样的方法安装不了XCode3.2.6,而且导致系统直接“五国”,挽救方法可以参考上一篇。

附录:各个版本的XCode的下载地址



    
[3] 浅析Objective-C 轻重缓急拷贝
    来源: 互联网  发布时间: 2014-02-18
浅析Objective-C 深浅拷贝

先了解下概念:

浅 复 制:在复制操作时,对于被复制的对象的每一层复制都是指针复制。

深 复 制:在复制操作时,对于被复制的对象至少有一层复制是对象复制。

完全复制:在复制操作时,对于被复制的对象的每一层复制都是对象复制。


注:

1、在复制操作时,对于对象有n层是对象复制,我们可称作n级深复制,此处n应大于等于1。

2、对于完全复制如何实现(目前通用的办法是:迭代法和归档),这里后续是否添加视情况而定,暂时不做讲解。

3、指针复制俗称指针拷贝,对象复制也俗称内容拷贝。

4、一般来讲:

          浅层复制:复制引用对象的指针。

          深层复制:复制引用对象内容。

       这种定义在多层复制的时候,就显得模糊。所以本文定义与它并不矛盾。反而是对它的进一步理解和说明。           
5、

retain:始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。

copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,

         引用计数每次加一。始终返回一个不可变对象。

mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象。

例子:

NSMutableString *mstr = [NSMutableString stringWithString:@"origin"];

         NSString *strCopy = [mstr copy];

         NSMutableString *mstrCopy = [mstr copy];

         NSMutableString *mstrMCopy = [mstr mutableCopy]; 

         // [mstrCopy appendString:@"1111"];        // error

         [mstr appendString:@"222"];

          [mstrMCopy appendString:@"333"];

          // 以上四个对象所分配的内存都是不一样的。而且对于mstrCopy,它所指向的其实是一个imutable对象,是不可改变的,所以会出错,这点要注意,好好理解。

 

6、

不可变对象:值发生改变,其内存首地址随之改变。

可变对象:无论值是否改变,其内存首地址都不随之改变。

引用计数:为了让使用者清楚的知道,该对象有多少个拥有者(即有多少个指针指向同一内存地址)。

 

最近有一个好朋友问我,什么时候用到深浅复制呢?那么我就把我所总结的一些分享给大家,希望能帮助你们更好的理解深浅复制喔!

那么先让我们来看一看下边数组类型的转换

1、不可变对象→可变对象的转换:

       NSArray *array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

       NSMutableArray  *str2=[array1 mutableCopy];

2、可变对象→不可变对象的转换:

    NSMutableArray *array2   = [NSMutableArray arrayWithObjects:@"aa",@"bb",@"cc",@"dd",nil];

       NSArray *array1=[  array2    Copy];

3、可变对象→可变对象的转换(不同指针变量指向不同的内存地址):

       NSMutableArray *array1= [NSMutableArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

       NSMutableArray  *str2=[array1 mutableCopy];

通过上边的两个例子,我们可轻松的将一个对象在可变和不可变之间转换,并且这里不用考虑内存使用原则(即引用计数的问题)。没错,这就是深拷贝的魅力了。

4、同类型对象之间的导向保持(不同指针变量指向同一块内存地址):

  a、

   NSMutableString *str1=[NSMutableString stringWithString:@"two day"];

   NSMutableString *str2=[str1   retain];

   [str1  release];

  b、

   NSArray *array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

   NSArray  *str2=[array1 Copy];

   [array1 release];

 

 通俗的讲,就是甲在执行交通导航任务,但接到上级新的命令要执行新的任务,那么在甲执行新任务之前,需要有人替代甲继续执行交通导航任务。这时候就要用到浅拷贝了。

则简化为:

问:什么时候用到深浅拷贝?

答:深拷贝是在要将一个对象从可变(不可变)转为不可变(可变)或者将一个对象内容克隆一份时用到;

     浅拷贝是在要复制一个对象的指针时用到。

 

下面看些例子总结:

//
//  main.m
//  TTTT
//
//  Created by NeuLion SH on 12-12-3.
//  Copyright (c) 2012年 NeuLion SH. All rights reserved.
//

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    
    @autoreleasepool {
        //第一种:非容器类不可变对象
        
        NSString *str1=@"one day";
        
        NSLog(@"\n初始化赋值引用计数为::::%lu",str1.retainCount);
        NSString *strCopy1=[str1 retain];
        printf("\n继续retain引用计数为:::%lu",str1.retainCount);
        NSString *strCopy2=[str1 copy];
        printf("\n继续copy后引用计数为::::%lu",str1.retainCount);
        NSString *strCopy3=[str1 mutableCopy];
        printf("\n继续mutableCopy后为:::%lu\n",str1.retainCount);
        
        printf("\n非容器类不可变对象\n原始地址::::::::::%p",str1);
        printf("\nretain复制::::::::%p",strCopy1);
        printf("\ncopy复制::::::::::%p",strCopy2);
        printf("\nmutableCopy复制:::%p",strCopy3);
        
        //这里说明该类型不存在引用计数的概念
        
        // 初始化赋值引用计数为:18446744073709551615
        // 继续retain引用计数为:18446744073709551615
        // 继续copy后引用计数为:18446744073709551615
        // 继续mutableCopy后为:18446744073709551615
        
        //非容器类不可变对象
        //原始地址::::::::::0x1000033d0
        //retain复制::::::::0x1000033d0//浅复制
        //copy复制::::::::::0x1000033d0//浅复制
        //mutableCopy复制:::0x10010c420//深复制
        
        
        printf("\n");
        //第二种:容器类不可变数组
        NSArray *array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];
        
        printf("\n初始化赋值引用计数为::::::::::::%lu",array1.retainCount);
        NSArray *arrayCopy1 = [array1 retain];
        printf("\n继续retain后引用计数为:::::::::%lu",array1.retainCount);
        NSArray *arrayCopy2 = [array1 copy];
        printf("\n继续copy后引用计数为:::::::::::%lu",array1.retainCount);
        NSArray *arrayCopy3 = [array1 mutableCopy];
        printf("\n继续mutableCopy后引用计数为::::%lu\n",array1.retainCount);
        
        printf("\n容器类不可变数组\n原始地址::::::::::%p\t\t%p",array1,[array1 objectAtIndex:1]);
        printf("\nretain复制::::::::%p\t\t%p",arrayCopy1,[arrayCopy1 objectAtIndex:1]);
        printf("\ncopy复制::::::::::%p\t\t%p",arrayCopy2,[arrayCopy2 objectAtIndex:1]);
        printf("\nmutableCopy复制:::%p\t\t%p",arrayCopy3,[arrayCopy3 objectAtIndex:1]);
        
        
        //初始化赋值引用计数为::::::::::::1
        //继续retain后引用计数为:::::::::2
        //继续copy后引用计数为:::::::::::3
        //继续mutableCopy后引用计数为::::3
        
        //容器类不可变数组
        //原始地址::::::::::0x10010c6b0 0x100003410
        //retain复制::::::::0x10010c6b0 0x100003410//浅复制
        //copy复制::::::::::0x10010c6b0 0x100003410//浅复制
        //mutableCopy复制:::0x10010c760 0x100003410//深复制
        
        
        printf("\n");
        //第三种:非容器类可变对象
        
        NSMutableString *str2=[NSMutableString stringWithString:@"two day"];
        
        printf("\n初始化赋值引用计数为::::::::::::%lu",str2.retainCount);
        NSMutableString *strCpy1=[str2 retain];
        printf("\n继续retain后引用计数为:::::::::%lu",str2.retainCount);
        NSMutableString *strCpy2=[str2 copy];
        printf("\n继续copy后引用计数为:::::::::::%lu",str2.retainCount);
        NSMutableString *strCpy3=[str2 mutableCopy];
        printf("\n继续mutableCopy后引用计数为::::%lu\n",str2.retainCount);
        
        printf("\n非容器类可变对象\n原始地址::::::::::%p",str2);
        printf("\nretin复制::::::::%p",strCpy1);
        printf("\ncopy复制::::::::::%p",strCpy2);
        printf("\nmutableCopy复制:::%p",strCpy3);
        
        
        
        //初始化赋值引用计数为::::::::::::1
        //继续retain后引用计数为:::::::::2
        //继续copy后引用计数为:::::::::::2
        //继续mutableCopy后引用计数为::::2
        
        //非容器类可变对象
        //原始地址::::::::::0x10010c560
        //retain复制::::::::0x10010c560//浅复制
        //copy复制::::::::::0x100102720//深复制
        //mutableCopy复制:::0x10010c880//深复制
        
        printf("\n");
        //第四种:容器类可变数组
        
        NSMutableArray *array2   = [NSMutableArray arrayWithObjects:@"aa",@"bb",@"cc",@"dd",nil];
        
        printf("\n初始化赋值引用计数为::::::::::%lu",array2.retainCount);
        NSMutableArray *arrayCpy1 = [array2 retain];
        printf("\n继续retain后引用计数为:::::::%lu",array2.retainCount);
        NSMutableArray *arrayCpy2=[array2 copy];
        printf("\n继续copy后引用计数为:::::::::%lu",array2.retainCount);
        NSMutableArray *arrayCpy3 = [array2 mutableCopy];
        printf("\n继续mutableCopy后引用计数为::%lu\n",array2.retainCount);
        
        printf("\n容器类可变数组\n原始地址:::::::::::%p\t%p",array2,[array2 objectAtIndex:1]);
        printf("\nretain复制:::::::::%p\t%p",arrayCpy1,[arrayCpy1 objectAtIndex:1]);
        printf("\ncopy复制:::::::::::%p\t%p",arrayCpy2,[arrayCpy2 objectAtIndex:1]);
        printf("\nnmutableCopy复制:::%p\t%p",arrayCpy3,[arrayCpy3 objectAtIndex:1]);
        
        
        //初始化赋值引用计数为::::::::::1
        //继续retain后引用计数为:::::::2
        //继续copy后引用计数为:::::::::2
        //继续mutableCopy后引用计数为::2
        
        //容器类可变数组
        //原始地址:::::::::::0x10010e6c0 0x1000034b0
        //retain复制:::::::::0x10010e6c0 0x1000034b0//浅复制
        //copy复制:::::::::::0x10010e790 0x1000034b0//深复制
        //nmutableCopy复制:::0x10010e7c0 0x1000034b0//深复制
        
        
        ///////////////////////////////////
        printf("\n");
        //一、容器内的元素内容都是浅拷贝
        NSArray *mArray1 = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
        printf("\nmArray1 retain count: %ld",[mArray1 retainCount]);   // 1
        printf("\nretain复制:::::::::%p\t%p",mArray1,[mArray1 objectAtIndex:1]);
        NSArray *mArrayCopy2 = [mArray1 copy];
        printf("\nmArray1 retain count: %ld",[mArray1 retainCount]);  // 2
        printf("\ncopy复制:::::::::::%p\t%p",mArrayCopy2,[mArrayCopy2 objectAtIndex:1]);
        // mArray1和mArrayCopy2指向同一对象,retain值+1
        NSMutableArray *mArrayMCopy1 = [mArray1 mutableCopy];
        printf("\nmArray1 retain count: %ld ",[mArray1 retainCount]);    //2
        printf("\nnmutableCopy复制:::%p\t%p \n",mArrayMCopy1,[mArrayMCopy1 objectAtIndex:1]);
        
        //mArrayCopy2和mArray1指向的是不一样的对象,但是其中的元素都是一样的对象----同一个指针
        NSMutableString *testString = [mArray1 objectAtIndex:0];
        //testString = @"1a1"; // 这样会改变testString的指针,其实是将@"1a1"临时对象赋给了testString
        [testString appendString:@"tail"]; //  这样以上三个数组的首元素都被改变了
        NSLog(@"%@",mArray1);
        NSLog(@"%@",mArrayCopy2);
        NSLog(@"%@",mArrayMCopy1);
        // 由此可见,对于容器而言,其元素对象始终是指针复制。如果需要元素对象也是对象复制,就需要实现深拷贝。
        /*
         mArray1 retain count: 1
         retain复制:::::::::0x100503820	0x100002150
         mArray1 retain count: 2
         copy复制:::::::::::0x100503820	0x100002150
         mArray1 retain count: 2
         nmutableCopy复制:::0x100503850	0x100002150
         (
         atail,
         b,
         c
         )
         (
         atail,
         b,
         c
         )
         (
         atail,
         b,
         c
         )
         */
        
        
        //二、
        NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"first"],[NSString stringWithString:@"b"],@"c",nil];
        printf("\narray retain count: %ld",[array retainCount]);   // 1
        printf("\n原始:::::::::%p \t%p\t%p\t%p",array,[array objectAtIndex:0],[array objectAtIndex:1],[array objectAtIndex:2]);
        NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array copyItems:YES];
        printf("\narray retain count: %ld",[array retainCount]);   // 1
        printf("\ncopyItems:::::::::%p\t%p\t%p\t%p",deepCopyArray,[deepCopyArray objectAtIndex:0],[deepCopyArray objectAtIndex:1],[deepCopyArray objectAtIndex:2]);
        NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];
        printf("\narray retain count: %ld",[array retainCount]);   // 1
        printf("\narchive:::::::::%p\t%p\t%p\t%p",trueDeepCopyArray,[trueDeepCopyArray objectAtIndex:0],[trueDeepCopyArray objectAtIndex:1],[trueDeepCopyArray objectAtIndex:2]);
        // trueDeepCopyArray是完全意义上的深拷贝,而deepCopyArray则不是,对于deepCopyArray内的不可变元素其还是指针复制。或者我们自己实现深拷贝的方法。因为如果容器的某一元素是不可变的,那你复制完后该对象仍旧是不能改变的,因此只需要指针复制即可。除非你对容器内的元素重新赋值,否则指针复制已足够。
        // 举个例子,[[array objectAtIndex:0] appendString:@"sd"]后其他的容器内对象并不会受影响。[array objectAtIndex:1,2]和[deepCopyArray objectAtIndex:1,2]尽管是指向同一块内存,但是我们没有办法对其进行修改-----因为它是不可改变的。所以指针复制已经足够。所以这并不是完全意义上的深拷贝。
        
    }
    return 0;
}

 再看NSDictionary的完全复制的实现:

#import <Foundation/Foundation.h>

@interface NSDictionary (MutableDeepCopy)
- (NSMutableDictionary *)mutableDeepCopy;
@end



#import "NSDictionary+MutableDeepCopy.h"

@implementation NSDictionary (MutableDeepCopy)

- (NSMutableDictionary *)mutableDeepCopy {
    NSMutableDictionary *returnDict = [[NSMutableDictionary alloc]
                                       initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys) {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;
        
        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [returnDict setValue:oneCopy forKey:key];
    }
    return returnDict;
}

@end

 

 

 

 

 

 

 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3