2009年3月2日星期一
关于创建一个类
如果是instance method正好相反,在返回值前面加一个“-”号。
在同一个类的声明中,class method 可以跟instance method重名,另外method也可以与某个instance veriable重名,这种情况比较常见,往往用于获取这个instance veriable的值的方法中。
在声明返回值的时候可以用标准C 的语法将返回类型转换成需要的类型,比如
- (float)radius;
另外,如果这个method带有参数,且参数也需要转换类型的话,这往往是有必要的,因为不能保证调用参数的时候传入的参数类型就正好是相符的。比如
- (void)setRadius:(float)aRadius;
注意,在定义method的时候如果不显示的说明返回值或者传入参数的类型,那么缺省的类型就是id,
如果method有一堆参数的话,如此定义。
- makeGroup:group, ...;
- (void)setWidth:(float)width height:(float)height;
Class Name的用途
Rectangle *anRect;
另外一种用途是用作Class Object,但是注意,用作Class object的时候一定是要放在一个message expression中,当作一个receiver来用的时候方才可以。比如
if ( [anObject isKindOfClass:[Rectangle class]] )
而不能写成
if ( [anObject isKindOfClass: Rectangle] )
2009年3月1日星期日
metaclass object
除此之外compiler还会为每个类生成一个metaclass object,它使用来描述class object的,但是它只在内部被runtime system使用,用户是用不到它的。
Class Object的重要的作用就是生成instance,例如如下的代码
id myRect;
myRect = [Rectangle alloc];
这里Rectangle 是一个Class Object ,传给它一个alloc message然后返回的指针就赋给myRect了。便生成了一个instance myRect.
Class Method 和 instance Method
举一个例子,
int versionNumber = [Rectangle version];
除了这样你还可以这样
id aClass = [anObject class];
id rectClass = [Rectangle class];
因为Class Object和其他任何object一样都能被定义成id类型,因为他们都是Object,同样的任何Class Object都是属于Class这个类,所以我们同样可以type成Class.
这是两种获知id指针的方式,即可以向一个instance 传一个class消息,也可以向一个class object也就是用Rectangle来代表的这个传一个message消息,都能获知id
Class aClass = [anObject class];
Class rectClass = [Rectangle class];
Static typing
static typing的好处很多,但是不能取代dynamic binding 和 dynamic determination of a receiver's class.
任何一种对象,都可以用它所属类的父类来声明,编译的时候没所谓,runtime的时候会找出来它真正属于的类。NSObject中间还有两个方法用于揭示一个对象究竟属于那个类,他们分别是isMemberOfClass 和 isKindOfClass,这两个方法传入的参数都是someClass ,返回值是一个bool值,其中isMemberOfClass 是用以判断这个Object是不是后面那个传入的类的实例,另外一个方法isKindOfClass是用于判断这个Object 是不是后面那个传入类的实例又或者是是它父类的实例。总之是要判断这个Object是否在后面传入这个类的继承树上。
另外Objective-C中的abstract Class 与其他语言的中的规定有所不同,它没有专门标注这种抽象类的说明符号,也并不禁止从抽象类生成实例,但是因为抽象类中的很多方法并没有完成,所以即便是生成了抽象类的实例大多数情况下也没什么用处,不过也有例外,就是NSView这个类,经常被直接的使用,而另外一个经典的例子就是NSObject如果你生成一个这样的实例将什么也做不了。
2009年2月9日星期一
MVC概念以及iphone开发中的属性
View : 所有的用户能看到的诸如窗体之类,还有用户能用来操作的控件
Controller: 程序逻辑,用于连接 model和view的部分,知道如何处理用户的输入,如何来响应事件.
Controller 里面的类可以通过一个特殊的变量实例outlet来引用nib里的对象,这个实例就如同一个指针指向了nib中的对象. Controller里面要操作一个nib里的对象的时候可以先声明一个outlet然后将这个outlet指向想要操作的对象,然后通过这个outlet就可以操作指向的对象了.
从操作的另外一个方向来讲,也可以在nib文件中创建接口对象,用以激发在controller中的特别处理,这类处理就称之为动作action,加入当手指离开一个按钮的时候,这本身就是一个事件,这个事件发生的时候你的controller里面的一个method就可能被触发.
(IBAction)dosomething:(id)sender 这是action方法的声明方式,注意,后面的sender是可选的,即便你声明的时候有这个sender,使用的时候也完全可以不带.
在定义一个property的时候,在"property"关键字后面带的括号中的可选属性,如果property操作的对像是一个raw type(基本类型) 比如int则不需要带retain关键字,如果操作的对像是用户构建的其他的非简单类型,则必须要带这个attribute不然就有可能在你还需要操作这个对象的时候它就已经被从内存中清除了.
到这一步一个属性的开头应该是 @property (retain,) 当然后面还有别的东西,慢慢讲. 另外一个attribute是nonatomic,其实为了实现多线程的应用,还可以选别的,但是那样会增加不必要的开销,尽管开销不大,还是应该避免,大多数情况下,这里要用nonatomic,后面其实还会看到不用nonatomic的情况.
2009年2月1日星期日
IGMP v1 notes
一台主机上只要还有包含至少一个进程的多播组,就需要对多播路由器下发的查询报文发送报告报文.
如果一台主机上已经没有了多播组,则下次多播路由器下发查询报文的时候就不发报告报文就可以了.
多播路由器搜集了所有接口上的所有主机发送过来的报告报文,就知道自己下辖的主机们当前还在加入着哪些多播组,这样多播路由器便可以向它的上级进行报告了.
主机在报告的时候对每一个至少还含有一个进程的多播组都要发送一个报告,报告报文中IGMP后四个Byte正是这个多播组的地址, 但对于查询报文,这里是全零,也就是32个零.
重要)
主机的报告报文中的IP头部,源IP地址就是主机地址,目的IP地址是所报告的组地址,在多播路由器下发的查询报文的IP头部中,源IP地址是多播路由地址,目的地址是个224.0.0.1这个地址是保留多播地址,意思是发往子网内所有的系统组. (224.0.0.2)是发往所有的多播路由器
规则)
当第一个进程加入一个多播组的时候,主机要发送一个报告,这个报告并不能保证一定会被多播路由器收到,所以为了保险期间,过一定时间之后主机会重新发送一个报告,这个时间一般在0-10秒之间.
当多播路由器发起一个查询的时候,因为子网内可能有很多主机都加入同一个多播组,这个时候主机收到了查询报文之后并不急于发送报告报文,而是会后延一个时延,当子网中有一个主机发送应查询的要求发送了一个报告报文之后,因为目的地址是这个要报告的多播组的组地址,那么这个报告报文便可以被子网内所有同在这个多播组的其他主机收到,其他主机看到有人已经报告了这个多播组的存在,便可以不再发送关于这个多播组的报告报文了. 这样便减少了不要要的开销
在一个没有多播路由器的子网中,因为没有人发起查询,自然就不会有应查询而发出的报告报文,但是子网中的主机因为支持多播,所以当有进程在主机上加入了一个新的多播组的时候,主机还是会发出报告报文的,而这便是在没有多播路由器的子网中唯一的IGMP报文流量.
特别的多播组)
224.0.0.1是所有子网内支持多播的主机和路由都要自动加入的一个组,当接口初始化之后便自动加入这个组,这就是为什么抓包能够看到有些设备在启动的时候会自动加入到224.0.0.1这个组的原因,加入的方式是发送一个报告报文,宣称自己加入了这个组,所有在子网内的其他设备支持多播的设备都能收到这个报文,因为这个报文的目的地址是大家都加入的组224.0.0.1
TTL 一般多播报文的TTL 设定为1,这样可以控制多播报文在子网内传递,而不能被多播路由器转发.
有一个特别需要注意的地方就是对于特殊地址范围 224.0.0.0-224.0.0.255 被设定用于TTL 不大于1的应用,所以任何情况下多播路由器不会转发多播地址在这个范围内的多播报文.
2009年1月31日星期六
2009年1月28日星期三
Meet some friends during spring festival
This is my first attempt to upload video onto blogger and wish me good luck~
2009年1月13日星期二
The daily use Software on MacOS X
network analyser: Wireshark for mac
HD content player: Quick time
RMVB player: RealPlayerGold 11 for mac
There are also some other Applications have their mac editions.
Such as firefox, microsoft office, msn messenger, tencent QQ, Transmission for mac, Skype for mac
By default one can delete an installed mac software by simply delete the icon from the Application Directory directly and remov its icon from the DOCK. This is a coolest feature as my opinion.
2009年1月8日星期四
工厂模式
工厂模式定义:提供创建对象的接口.
为何使用?
工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随
为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的
我们以类Sample为例, 如果我们要创建Sample的实例对象:
Sample sample=new Sample();
可是,实际情况是,通常我们都要在创建sample实例时做点初
首先,我们想到的是,可以使用Sample的构造函数,
Sample sample=new Sample(参数);
但是,如果创建sample实例时所做的初始化工作不是象赋值这
为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,
在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开
这时我们就需要Factory工厂模式来生成对象了,
Sample mysample=new MySample();
Sample hissample=new HisSample();
随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
工厂方法
你会建立一个专门生产Sample实例的工厂:
| public class Factory{ public static Sample creator(int which){ //getClass 产生Sample 一般可使用动态类装载装入类。 } } |
那么在你的程序中,如果要实例化Sample时.就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,
使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Sample,
进一步稍微复杂一点,就是在工厂类上进行拓展,
抽象工厂
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
这两个模式区别在于需要创建对象的复杂程度上。
这里假设:Sample有两个concrete类SampleA
那么,我们就将上例中Factory变成抽象类,将共同部分封装
| public abstract class Factory{ public abstract Sample creator(); public abstract Sample2 creator(String name); } public class SimpleFactory extends Factory{ public Sample creator(){ public Sample2 creator(String name){ } public class BombFactory extends Factory{ public Sample creator(){ public Sample2 creator(String name){ }
|
从上面看到两个工厂各自生产出一套Sample和Sample2
抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产Samp
在实际应用中,工厂方法用得比较多一些,
举例
我们以Jive的ForumFactory为例,
| public abstract class ForumFactory { private static Object initLock = new Object(); public static ForumFactory getInstance(Authorization authorization) { try { //Now, 返回 proxy.用来限制授权对forum的访问 //真正创建forum的方法由继承forumfactory的 .... }
|
因为现在的Jive是通过数据库系统存放论坛帖子等内容数据,如
private static String className = "com.jivesoftware.forum.
你可以使用自己开发的创建forum的方法代替com.
在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Si
看看Java宠物店中的CatalogDAOFactory:
| public class CatalogDAOFactory { /** * 本方法制定一个特别的子类来实现DAO模式。 public static CatalogDAO getDAO() throws CatalogDAOSysException { CatalogDAO catDao = null; try { InitialContext ic = new InitialContext(); String className =(String) ic.lookup(JNDINames.CATALOG_ catDao = (CatalogDAO) Class.forName(className). } catch (NamingException ne) { throw new CatalogDAOSysException(" } catch (Exception se) { throw new CatalogDAOSysException(" } return catDao; } } |
CatalogDAOFactory是典型的工厂方法,catD
由此可见,
设计模式如何在具体项目中应用见《Java实用系统开发指南》
今天开张了
Objective-C 里面的Class
对于每一个Class编译器只创建一个可访问的Object,这个class object 知道如何创建属于这个类的新的对象,正因为这样的原因,这个对象被称之为factory object.
由这个对象创建的都是这个Class的实例,真正在程序中起作用的对象都是这个factory object在运行时创建的实例。每个实例对象都有各自独立的instance variables,但是他们的method都是共享的。
在命名的时候,习惯上将Class名的首字母大写,将实例对象名字的首字母小写。
比如,一个Class 名字可能是 Rectangle 一个相应的实例的名字可能是 myRect
由上可见,实例命名的时候第一个单词的首字母小写,之后的每个单词的首字母都应该大写














