<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>追梦 - WuLeilei's Blog</title>
<link>http://www.wuleilei.com</link>
<description>WuLeilei's Blog</description>
<language>zh-cn</language>
<generator>http://www.wuleilei.com</generator>
<item>
<title>iOS开发之回调delegate的方法时判断delegate是否已经被释放</title>
<link>http://www.wuleilei.com/blog/320</link>
<description><![CDATA[
	最近的项目遇到了网络请求，需要在请求完成后回调delegate的方法。然而回调时经常遇到这种情况：delegate已经被释放，这时调用其方法则会引起crash。

	objc的runtime中有两种判断类型的方式比较靠谱，他们可以直接取得任意一个objc_object（和id是完全一样的数据类型）的类或者类名。其函数如下：

//Returns the class name of a given object.
const char *object_getClassName(id obj);
 
//Returns the class of an object.
Class object_getClass(id object);

	第一个函数可以返回任意一个id的类名，第二个函数可以返回任意一个id的Class。这两个函数各有优劣。使用第一个函数判断类型是否改变的优点是在 iphone开发环境下默认公开，可以随便调用，缺点是要使用几字节的内存空间用于存放字符串，而且做字符串比较要稍微多花费一些CPU时间。第二个函数 优点是可以将获取的Class指针做为int型保存起来，只需要4字节，且比较起来节约CPU时间，坏处是我们要手动声明一下此函数才可以在自己的代码里 使用，否则会出现一个warning，提示&ldquo;Implicit declaration of function &lsquo;object_getClass&rsquo; is invalid in C99&rdquo;，不过手动声明一下只要加一行代码就可以，也不麻烦。

	下面是一个实例：

// WebService.h

#import &lt;Foundation/Foundation.h&gt;

@protocol ServiceDelegate;

@interface WebService : NSObject {
    id &lt;ServiceDelegate&gt; _myDelegate;
    Class _originalClass;
}

@property (nonatomic, assign) id myDelegate;

- (void)postDataWithURL:(NSString *)myURL postData:(NSDictionary *)dataDic setDelegate:(id)theDelegate;
- (void)serviceFun:(NSDictionary *)paramDic;

@end

@protocol ServiceDelegate &lt;NSObject&gt;
- (void)serviceCallBack:(id)resultObject serviceFlag:(NSInteger)flag;
@end

// WebService.m

#import &quot;WebService.h&quot;

Class object_getClass(id object);

@implementation WebService

@synthesize myDelegate = _myDelegate;

- (void)postDataWithURL:(NSString *)myURL postData:(NSDictionary *)dataDic setDelegate:(id)theDelegate
{
    self.myDelegate = theDelegate;
    _originalClass = object_getClass(theDelegate);
    [NSThread detachNewThreadSelector:@selector(serviceFun:) toTarget:self withObject:dataDic];
}

- (void)serviceFun:(NSDictionary *)paramDic
{
    Class currentClass = object_getClass(self.myDelegate);
    if (currentClass == _originalClass) {
        // 如果delegate没有被释放
    }
}

@end]]></description>
<pubDate>Wed, 01 Feb 2012 04:35:31 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>iOS开发之使用AES加密（兼容Objective-C与C#）</title>
<link>http://www.wuleilei.com/blog/319</link>
<description><![CDATA[
	项目中，难免会用到加密解密，最简单的加密莫过于md5，但md5毕竟不安全，密文被获取后容易被解密。

	最近在做iphone项目登录的时候，要求加密登录信息后再提交到服务器。在网上找了一些算法，像3DES之类的，都是比较安全的算法，但跨平台遇到了困难。服务器端是用.net开发的，解密后的密文解密后与最初的加密字符串不一致。

	经过多番折腾，终于找到了一对兼容iOS与C#的加解密算法：AES。

	关于AES，百度百科是这么说的：

	
		密码学中的高级加密标准（Advanced Encryption Standard，AES），又称Rijndael加密法，是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES，已经被多方分析且广为全世界所使用。经过五年的甄选流程，高级加密标准由美国国家标准与技术研究院 （NIST）于2001年11月26日发布于FIPS PUB 197，并在2002年5月26日成为有效的标准。2006年，高级加密标准已然成为对称密钥加密中最流行的算法之一。


	附件中是iOS版本与C#版本的加密与解密源码，需要的童鞋可以下载。

	点击此处下载示例。]]></description>
<pubDate>Tue, 31 Jan 2012 04:49:54 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>事情好多哦</title>
<link>http://www.wuleilei.com/blog/318</link>
<description><![CDATA[
	公司就我一个人做iOS，很孤单。和他们没有共同的&ldquo;语言&rdquo;，压力比较大，做不做得出来就我一个人。前几天因为一个奇怪的crash，郁闷的调试了两天，最后找了解决方法，却觉得这个问题很蹊跷，连个讨论的人也没有，很郁闷。

	元旦的时候参加了一个朋友的婚礼，我们可谓是&ldquo;青梅竹马&rdquo;哦，小时候的邻居，比我小一岁。山上捣鸟窝，水里捉虾，样样都少不了。但我们都是男的，不知道能不能也称为&ldquo;闺蜜&rdquo;，哈哈。

	婚礼后的一天，和老妈去看了一下装修的材料。昨天老爸又和老妈去把材料买了，今天早上叫了个车子行了四十几公里韵了过来，又和他们搬到楼上。简单的吃了个饭，和老妈去办了装修手续后她就坐车回去了。只有老爸和电工师傅在这里装修，年前估计就装个水电吧。

	下午回住的地方，刚到不久，就接到了电话，说大爷爷去世了。去年国庆节回去的时候就不能走路了的，去看了看他，怕后面没机会了。人老了，都八十多岁了。然后元旦的时候又去看了，这次更加没精神，躺在床上，勉强说了句话，大多数时候都只能点头示意，大家也知道，时间不多了。一路好走。]]></description>
<pubDate>Mon, 09 Jan 2012 14:10:15 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>iOS开发之获取本机IP地址的方法</title>
<link>http://www.wuleilei.com/blog/317</link>
<description><![CDATA[
	项目中需要获取本机IP并发送到服务器，之前在网上找了一段代码获取ip，模拟器运行正常，但在真机上得到的却是一段乱七八糟的字符串。又在网上找的一段代码，It works：

#define MAXADDRS 32

extern char *if_names[MAXADDRS];
extern char *ip_names[MAXADDRS];
extern char *hw_addrs[MAXADDRS];
extern unsigned long ip_addrs[MAXADDRS];

// Function prototypes

void InitAddresses();
void FreeAddresses();
void GetIPAddresses();
void GetHWAddresses();

/*
 *  IPAddress.c
 *
 */

#include &quot;IPAddress.h&quot;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/ioctl.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;netdb.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;sys/sockio.h&gt;
#include &lt;net/if.h&gt;
#include &lt;errno.h&gt;
#include &lt;net/if_dl.h&gt;
#include &quot;IPAddress.h&quot;

#define min(a,b) ((a) &lt; (b) ? (a) : (b))
#define max(a,b) ((a) &gt; (b) ? (a) : (b))
#define BUFFERSIZE 4000

char *if_names[MAXADDRS];
char *ip_names[MAXADDRS];
char *hw_addrs[MAXADDRS];
unsigned long ip_addrs[MAXADDRS];

static int   nextAddr = 0;

void InitAddresses()
{
int i;
for (i=0; i&lt;MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
ip_addrs[i] = 0;
}
}

void FreeAddresses()
{
int i;
for (i=0; i&lt;MAXADDRS; ++i)
{
if (if_names[i] != 0) free(if_names[i]);
if (ip_names[i] != 0) free(ip_names[i]);
if (hw_addrs[i] != 0) free(hw_addrs[i]);
ip_addrs[i] = 0;
}

InitAddresses();
}

void GetIPAddresses()
{
int                 i, len, flags;
char                buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifconf       ifc;
struct ifreq        *ifr, ifrcopy;
struct sockaddr_in *sin;
char temp[80];
int sockfd;
for (i=0; i&lt;MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = NULL;
ip_addrs[i] = 0;
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd &lt; 0)
{
perror(&quot;socket failed&quot;);
return;
}

ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, &amp;ifc) &lt; 0)
{
perror(&quot;ioctl error&quot;);
return;
}
lastname[0] = 0;
for (ptr = buffer; ptr &lt; buffer + ifc.ifc_len; )
{
ifr = (struct ifreq *)ptr;
len = max(sizeof(struct sockaddr), ifr-&gt;ifr_addr.sa_len);
ptr += sizeof(ifr-&gt;ifr_name) + len; // for next one in buffer
if (ifr-&gt;ifr_addr.sa_family != AF_INET)
{
continue; // ignore if not desired address family
}

if ((cptr = (char *)strchr(ifr-&gt;ifr_name, &#39;:&#39;)) != NULL)
{
*cptr = 0; // replace colon will null
}

if (strncmp(lastname, ifr-&gt;ifr_name, IFNAMSIZ) == 0)
{
continue; /* already processed this interface */
}
memcpy(lastname, ifr-&gt;ifr_name, IFNAMSIZ);
ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &amp;ifrcopy);
flags = ifrcopy.ifr_flags;
if ((flags &amp; IFF_UP) == 0)
{
continue; // ignore if interface not up
}
if_names[nextAddr] = (char *)malloc(strlen(ifr-&gt;ifr_name)+1);
if (if_names[nextAddr] == NULL)
{
return;
}

strcpy(if_names[nextAddr], ifr-&gt;ifr_name);
sin = (struct sockaddr_in *)&amp;ifr-&gt;ifr_addr;
strcpy(temp, inet_ntoa(sin-&gt;sin_addr));
ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);

if (ip_names[nextAddr] == NULL)
{
return;
}
strcpy(ip_names[nextAddr], temp);
ip_addrs[nextAddr] = sin-&gt;sin_addr.s_addr;
++nextAddr;
}

close(sockfd);

}

void GetHWAddresses()
{
struct ifconf ifc;
struct ifreq *ifr;
int i, sockfd;
char buffer[BUFFERSIZE], *cp, *cplim;
char temp[80];
for (i=0; i&lt;MAXADDRS; ++i)
{
hw_addrs[i] = NULL;
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd &lt; 0)
{
perror(&quot;socket failed&quot;);
return;
}

ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;
if (ioctl(sockfd, SIOCGIFCONF, (char *)&amp;ifc) &lt; 0)
{
perror(&quot;ioctl error&quot;);
close(sockfd);
return;
}

ifr = ifc.ifc_req;
cplim = buffer + ifc.ifc_len;
for (cp=buffer; cp &lt; cplim; )
{
ifr = (struct ifreq *)cp;
if (ifr-&gt;ifr_addr.sa_family == AF_LINK)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&amp;ifr-&gt;ifr_addr;
int a,b,c,d,e,f;
int i;
strcpy(temp, (char *)ether_ntoa(LLADDR(sdl)));
sscanf(temp, &quot;%x:%x:%x:%x:%x:%x&quot;, &amp;a, &amp;b, &amp;c, &amp;d, &amp;e, &amp;f);
sprintf(temp, &quot;%02X:%02X:%02X:%02X:%02X:%02X&quot;,a,b,c,d,e,f);
for (i=0; i&lt;MAXADDRS; ++i)
{
if ((if_names[i] != NULL) &amp;&amp; (strcmp(ifr-&gt;ifr_name, if_names[i]) == 0))
{
if (hw_addrs[i] == NULL)
{
hw_addrs[i] = (char *)malloc(strlen(temp)+1);
strcpy(hw_addrs[i], temp);
break;
}
}
}
}
cp += sizeof(ifr-&gt;ifr_name) + max(sizeof(ifr-&gt;ifr_addr), ifr-&gt;ifr_addr.sa_len);
}
close(sockfd);
}

//Somewhere in your code
- (NSString *)deviceIPAdress {
InitAddresses();
GetIPAddresses();
GetHWAddresses();
return [NSString stringWithFormat:@&quot;%s&quot;, ip_names[1]];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    ipAddress.text = [self deviceIPAdress];
}

	点击此处下载示例。]]></description>
<pubDate>Fri, 06 Jan 2012 04:31:46 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>简单记录PC上安装苹果系统</title>
<link>http://www.wuleilei.com/blog/316</link>
<description><![CDATA[
	小Y快陪伴我3年了，半年前给他换上了Snow Leopard，最近又给他换上了Lion，感觉不错。除了无线网卡驱动不了之外，其它的基本上快完美了。简单记录一下安装步骤，以备以后使用：

1、分区G(2G)，H(3G)，I(30G)，不格式化，分配盘符；
2、使用hfsexplorer提取InstallESD.dmg中的BaseSystem.dmg文件；
3、使用hfsexplorer载入BaseSystem.dmg，并创建可写的lion7.2.dmg文件；
4、将lion7.2.dmg使用硬盘安装助手写入G分区；
5、使用Paragon.Partition.Man.11.Personal_server将H分区合并到G分区；
6、安装MacDrive与JRE；重启后如果没有G盘符，则需要用安装Ext2Fsd为磁盘添加盘符；
7、删除G分区中的/System/Installation/Packages；
8、复制原版安装盘Mac OS X Install ESD的/Packages文件夹，到启动硬盘Mac OS X Base System的/System/Installation/；
9、将mach_kernel从InstallESD.dmg复制到G盘并替换原有此文件；
10、替换G盘/System/Library/PrivateFrameworks/Install.framework/Frameworks/OSInstall.framework/Versions/A/OSInstall；
11、替换G盘/System/Installation/Package/OSInstall.mpkg；
12、删除G盘中的/System/Library/Extensions/AppleIntelCPUPowerManagement.kext及AppleIntelCPUPowerManagementClient.kext
13、Y430删掉G盘中的S/L/E/AppleGraphicsControl.kext/Contents/PlugIns/ApplePolicyControl.kext(G460无需删除)；
14、安装BootThink；
15、启动G盘后抹掉I盘(Mac OS 扩展 - 日志式)；选择I盘为安装盘。
16、安装完成后，30秒倒计时后电脑就会重启动，抓紧这30秒打开终端，使用fdisk命令把C盘重新设回活动分区，打开终端，输入：
diskutil list（查看C：在哪里）
fdisk -e /dev/rdisk0
f  1（设置硬盘0分区1为活动分区）
w
y
quit
如果不想用命令行，则可以使用U盘PE或者光盘PE启动，进入PE使用磁盘分区软件将C盘设置为活动分区。]]></description>
<pubDate>Sat, 24 Dec 2011 05:14:43 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>解决MacDrive 8在WIN7 64位系统下不能识别苹果分区的办法</title>
<link>http://www.wuleilei.com/blog/315</link>
<description><![CDATA[
	最近安装Lion的时候，安装MacDrive 8后居然找不到苹果盘，原来是没有给盘分配盘符，但盘已经转换为苹果AF格式了，无法直接分配盘符。找到一款不错的软件Ext2Fsd解决了此问题。

	

	右键点要分配盘符的分区选&ldquo;更改装配点盘符&rdquo;，然后分配好盘符后按上图勾选，问题解决。]]></description>
<pubDate>Thu, 22 Dec 2011 05:06:45 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>检测U盘是否被扩容并修复</title>
<link>http://www.wuleilei.com/blog/314</link>
<description><![CDATA[
	前段时候，到电脑城去办事儿，看到路边小摊买的U盘挺便宜的，4G的25元，8G的45元，于是决定买个8G的，45元的8GU盘跟JS砍价到25，果断买下。小高兴了片刻。

	经过几天的使用，发现U盘奇慢无比，最要命的是拷进去的东西拷出来后没法使用，提示被损坏了。很肯定U盘是假的，没多少钱的东西，仍在一旁没理会。

	最近在网上看到U盘被扩容的事件，联想到之前的U盘，猜测估计是被扩容了，于是测试之：

	1、首先用MyDiskTest检测U盘是否被扩容：

	

	好家伙，居然把128M的U盘扩容为8G。

	好吧，那我们就将它还原为128M吧。

	2、用Chip Genius查看U盘新片型号：

	

	型号为CBM2093p。

	3、在网上找CBM2093p对应的量产工具来恢复U盘的实际容量，这下更好了，恢复容量后：

	

	好吧，直接扔垃圾桶吧。]]></description>
<pubDate>Sun, 18 Dec 2011 04:40:55 +0800</pubDate>
<author>wuleilei</author>
</item>
<item>
<title>Mac OS X 中配置PHP的MCrypt扩展</title>
<link>http://www.wuleilei.com/blog/313</link>
<description><![CDATA[
	MCrypt是一个功能强大的加密算法扩展库，它包括有22种算法。Mac OS X 7预安装了PHP5.3.6，但没有安装MCrypt扩展，下面我们安装此扩展（据说安装前要先在电脑里安装XCODE,要不编译不了软件，因为我已经安装了xcode，所以无法验证是否必须先安装xcode)；

	1.下载并解压libmcrypt-2.5.8.tar.bz2；

	2.在终端执行如下命令：

cd ~/Downloads/libmcrypt-2.5.8/
./configure &ndash;disable-posix-threads &ndash;enable-static
make
sudo make install

	3.下载并解压PHP；

	4.在终端执行如下命令：

cd ~/Downloads/php-5.3.6/ext/mcrypt
phpize
./configure
make
cd modules
sudo cp mcrypt.so /usr/lib/php/extensions/no-debug-non-zts-20090626/

	5. 打开php.ini：

sudo vi /etc/php.ini

	（1）设置enable_dl = On；
	（2）查看;extension_dir = &quot;./&quot;前面的分号是否有（需要保留）；
	（3）Dynamic Extensions section中加入：

extension=/usr/lib/php/extensions/no-debug-n on-zts-20090626/mcrypt.so

	保存后退出，然后重启apache（sudo apachectl restart）。

	访问http://localhost/~[用户名]/phpinfo.php，搜索mcrypt，如果找得到，就表示MCrypt扩展库安装成功了。]]></description>
<pubDate>Fri, 09 Dec 2011 07:31:03 +0800</pubDate>
<author>wuleilei</author>
</item>
</channel>
</rss>
