Search This Blog

Saturday, March 27, 2010

保持圆角的CCSprite

@interface StretchableSprite : CCSprite {

}
+(id)spriteWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap;
-(id)initWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap;
@end


@implementation StretchableSprite
+(id)spriteWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap{
return [[[self alloc] initWithFile:file size:size leftCap:leftcap topCap:topcap] autorelease];
}

-(id)initWithFile:(NSString*)file size:(CGSize)size leftCap:(NSInteger)leftcap topCap:(NSInteger)topcap{
UIImage* image = [UIImage imageNamed:file];
CGImageRef base = image.CGImage;
CGContextRef context = CGBitmapContextCreate(nil,
size.width,
size.height,
CGImageGetBitsPerComponent(base),
4 * size.width,
CGImageGetColorSpace(base),
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);

float BASE_COL_WIDTH[] = {leftcap,1,image.size.width - leftcap -1};
float BASE_ROW_HEIGHT[] = {topcap,1,image.size.height - topcap -1};
float BASE_COL_X[] = {0,leftcap,leftcap + 1};
float BASE_ROW_Y[] = {0,topcap,topcap +1};

float TARGET_COL_WIDTH[] = {BASE_COL_WIDTH[0], size.width - BASE_COL_WIDTH[0] - BASE_COL_WIDTH[2], BASE_COL_WIDTH[2]};
float TARGET_ROW_HEIGHT[] = {BASE_ROW_HEIGHT[0], size.height - BASE_ROW_HEIGHT[0] - BASE_ROW_HEIGHT[2], BASE_ROW_HEIGHT[2]};
float TARGET_COL_X[] = {0,TARGET_COL_WIDTH[0],TARGET_COL_WIDTH[0]+TARGET_COL_WIDTH[1]};
float TARGET_ROW_Y[] = {size.height - TARGET_ROW_HEIGHT[0],
size.height - TARGET_ROW_HEIGHT[0] - TARGET_ROW_HEIGHT[1],
size.height - TARGET_ROW_HEIGHT[0] - TARGET_ROW_HEIGHT[1] - TARGET_ROW_HEIGHT[2]};

for (int row=0; row<3; row++) {
for (int col=0; col<3; col++) {
CGRect source = CGRectMake(BASE_COL_X[col], BASE_ROW_Y[row], BASE_COL_WIDTH[col], BASE_ROW_HEIGHT[row]);
CGRect target = CGRectMake(TARGET_COL_X[col], TARGET_ROW_Y[row], TARGET_COL_WIDTH[col], TARGET_ROW_HEIGHT[row]);
CGImageRef ref = CGImageCreateWithImageInRect(base, source);
CGContextDrawImage(context, target, ref);
CFRelease(ref);
}
}
CGImageRef final = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return [super initWithCGImage:final key:@"stretchable"];
}
@end

Sunday, March 21, 2010

如何在你的应用程序中使用Openfeint (在线排行 成就系统 挑战功能)



游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能,这样的好处有很多,比较特别的有两点。
1. 不用考虑虚拟键盘调用后进行的用户名输入,我就是觉得做个虚拟键盘输入名字做rank让我很崩溃所以才出此“下策”
2. 即时监控用户登录情况,随着每个用户的成绩提交,可以大致知道自己的游戏有多少用户。

目前我们的选择有两个,一个是plus+ ,本来我想用它,因为我觉得plus+这个logo和颜色跟我的游戏内容比较合,奈何落花有意流水无情,我申请完等了一个星期后被他否掉 ,在这样半被迫的情况下,我选择了openfeint,并且深深为它的功能所折服,不敢专美,与各位有需要的朋友分享。

注意,我这里说的情况是在原生程序中使用openfeint,u3d的引擎的不在我的讨论之列。另外我是web程序员出身,很多描述也许不够专业和精确,请各位指出及海涵。

首先,在官网注册为开发者,建立一个项目,你会得到一个项目的client id(用于提问),一个产品编号跟一个密钥,这将放置于程序中,注意不要输错,我曾经因为少粘贴了一位密钥
结果载入程序界面老是报莫名的错误。后来还是经过Fwish版主的提醒(他也曾经遇到一样的报错),才发现问题所在。
在官网下载SDK,察看它包里的readme,注意看 Building OpenFeint With Your Project 部分
一步一步照做,注意第九步 9. You must have a prefix header. It must have the following line: #import "OpenFeintPrefix.pch"
这个是加在 项目名_Prefix.pch这个文件的最后就可以了。
一般来说,编译出 4000多个错的话,多半是这里没加。另外要将所有#import到openfeint头文件的.m文件的扩展名通通改为.mm,以实现objectC和 C++的混合编译。

完成以上步骤后,可以尝试编译一下,能够顺利编译就没有问题了。

接下来要做的可以在 openfeint附带的sample里面看到,它的sample写得还是比较仔细的,不过它用的是UIKit和nib文件,所以开发游戏的还要根据自己的引擎做一些修改。

首先,在"项目名AppDelegate.mm"的文件里加入openfeint的载入定义部分,以让其在每次程序 load完以后就起作用。
- (void) startup
{
ofDelegate = [MyOFDelegate new];
//ofNotificationDelegate = [SampleOFNotificationDelegate new];
//ofChallengeDelegate = [SampleOFChallengeDelegate new];
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: UIDeviceOrientationPortrait],
OpenFeintSettingDashboardOrientation,@"ArithMaster",
OpenFeintSettingShortDisplayName,
[NSNumber numberWithBool:YES],
OpenFeintSettingEnablePushNotifications,
[NSNumber numberWithBool:NO],
OpenFeintSettingDisableUserGeneratedContent,nil];
ofChallengeDelegate = [MyChallengeDelegate new];
OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate
andChallengeDelegate:ofChallengeDelegate
andNotificationDelegate:nil];
//OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
[OpenFeint initializeWithProductKey:@"这里输入key"
andSecret:@" 这里输入密钥"
andDisplayName:@"Airthmetic Master"
andSettings:settings // see OpenFeintSettings.h
andDelegates:delegates]; // see OFDelegatesContainer.h
}

代码中ofDelegate和ofChallengeDelegate两个代理分别对应于OF的启动以及challenge模式的启动。
这两个类的具体写法可以参考sample中的例子,我基本上照抄了。

这样做完以后,可以通过执行 [OpenFeint launchDashboard]来进入OF界面,官方文档中建议这个可以作为一个按钮的绑定方法来实现。

另外重要的文档就在开发者界面里面指定功能里,点击问号会进入帮助界面,会告诉你功能相关头文件和基本的用法,注意调用方法的时候需要察看一下是否包含了带有该方法的头文件。

接下来我说说怎么提交成绩,很简单,就一句 [OFHighScoreService setHighScore: score forLeaderboard:@"排行榜id" onSuccess:OFDelegate() onFailure:OFDelegate()];
这个排行榜id是通过在leaderboard里面新建leaderboard取得的,在它的配置选项里可以选择成绩按照降序还是升序排列。一般都认为成绩是降序的,其实也不其然,比如我的《算术大师》,时间越短排行越高,就要按照升序排列。

至于提交成就也就一句 [OFAchievementService unlockAchievement: @"成就id" onSuccess: OFDelegate() onFailure: OFDelegate()];
这些成就可以在任何条件判断后执行,比如我指定了一个成就在成绩低于12秒的时候触发,就可以写 if(costsecond < 12) 触发成就 ,可以放心的是在你解锁了该成就以后,再次达到成就触发条件也不会重复触发成就。

以上两个都是OF的基本功能,使用也相对简单,我接下来要说的是高级功能里面的challenge,我为这个折腾了两个晚上,苦于资料稀缺,无人可问,终于攻克。
challenge就是挑战功能,我的理解是它其实是一种延时对战机制,用户A在完成了指定的游戏以后,可以将游戏过程数据和结果打包传输到OF的服务器上,然后你的被挑战者从服务器上下载这些数据,以跟你同样的条件进行游戏,并且在最后跟你的游戏成绩比较,这样就完成了一次挑战的过程。大家或许也想到了,在《算术大师》里,这种机制跟游戏的相性天然吻合,我的实现是把“被挑战者下载数据以后做完题目跟挑战者比较”这个过程当成两个西部牛仔的对决,谁速度更快,谁就能够打落对方的帽子。OF的文档里提到,这个同样适用于赛车游戏的场合,挑战者的数据可以作为一辆幽灵车显示在被挑战者的画面中,可以想见,被挑战者更加不允许犯错,所以还是能够增加游戏的乐趣和对抗程度的。

下面说说代码,首先是发送挑战,这个相对简单,直接上代码吧
- (void)_sendChallenge
{
ChallengeData data;

data.score = score; //给挑战数据赋值

NSData* challengeData = [NSData dataWithBytes:(void const*)&data length:sizeof(ChallengeData)]; //这句对我来说比较深奥了,只有敬畏地照抄了


[OFChallengeService
displaySendChallengeModal:@"挑战编号"
challengeText:[NSString stringWithFormat:@"my score is %d,come on!", score]
challengeData:challengeData];
}



- (void)challenge:(id)sender{

if ([OpenFeint hasUserApprovedFeint])
{
[self _sendChallenge];
}
else
{
OFDelegate nilDelegate;
OFDelegate sendChallengeDelegate(self, @selector(_sendChallenge));
[OpenFeint presentUserFeintApprovalModal:sendChallengeDelegate deniedDelegate:nilDelegate];
}
}

千万注意!根据我的实测,挑战数据似乎是C++的变量比较不会出问题,我用 NSString,NSMutableString结果在打包上传,下载解包后变成了空值,我熬的两个晚上有一个多晚上都在搞这个,结果用了C++的数组,立马就没事情了,所以,可能打包进去的数据需要类似这样的处理data.leftnum=[leftnum objectAtIndex:i] intValue];


challenge的delegate,主要是在这个函数里处理
- (void)userLaunchedChallenge:(OFChallengeToUser*)challengeToLaunch withChallengeData:(NSData*)challengeData
前面一个参数里面有挑战的名称,用户等信息,后面一个 NSData里面则是完整的游戏过程数据。
这个只要按照sample里照做就可以了。设置完成后,用户在openfeint内接受挑战后将以这个 delegate为入口进行后续的游戏过程处理。

最后是挑战结果处理,一般就是写个方法判断输赢平,然后设置两个回调方法
OFDelegate success(self, @selector(_submittedCompletedChallenge));
OFDelegate failure(self, @selector(_failedSubmittingCompletedChallenge));
[OFChallengeService
submitChallengeResult:challenge.resourceId
result:challenge.result
resultDescription:[NSString stringWithFormat:@"my score is %d,see you next time!", correctnum]
onSuccess:success
onFailure:failure];
我建议在 _submittedCompletedChallenge不要回传数据,似乎要按照传过来的数据的格式才行,否则会出错,而回传数据只有一种情况需要用到:就是被挑战者反复尝试挑战挑战者。

challenge的适用大致就是如此了,不解的话,建议反复研究OF自带的sample,另外挑战模式的测试需要用户注册两个帐户通过在OF的界面下切换来调试,当然,一模拟器一设备是最理想的。

有一些挑战相关的数据,都是可以从它传给delegate的两个参数里取得的,比如我在游戏里设置了一个成就,就是在"little Cocoa"发出的挑战中打败little Cocoa,则能获得游戏中最大的一个成就:超越开发者,这就需要判断传过来的用户名,通过对OF的源码的研究,我以这样的方式取得了用户名: [challenge.challenge.challenger name] ,当时觉得自己很牛逼,哈哈。

以上大致就是我在使用 openfeint过程中的一点心得,如果有问题的话请向我提出,如果知道的话,我会尽量解答。
另外OF其实提供了很完备的社区功能,你可以在系统里面发布公告,跟你的用户通过游戏内置的论坛进行交流,发pm给你的用户,这些原本需要复杂代码实现的功能都已经由其替你实现。所以确实能够让你的游戏从一个单机游戏进入多人游戏的世界,从何在乐趣上进步一个台阶。
最后我用一句xbox的口号结束这个教程,这也被写在了我游戏的loading页面:Game Experience may change during online play via openfeint !

Thursday, March 18, 2010

Sound iPhone


#import

@interface CSSound : NSObject {

}
+(void)playSound:(NSString *)soundName;
@end



#import "CSSound.h"
#import

@implementation CSSound
+(void)playSound:(NSString *)soundName{
SystemSoundID mySSID;
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:soundName];

OSStatus error = AudioServicesCreateSystemSoundID( (CFURLRef)[NSURL fileURLWithPath:path], &mySSID);

if(error == kAudioServicesNoError){
//DLog(@"successfully contructed sound %@", soundName);
AudioServicesPlaySystemSound(mySSID);
}else{
DLog(@"error playing sound %@", soundName);
}
}
@end

Wednesday, March 17, 2010

Soap

最近研究了下soap,找不到iphone上好用的soap代码.发现坛子,关于soap的东西也不多,就把自己写的贴出来,请大家批评指正吧。

用到的提供soap接口的网址是:[url]http://www.Nanonull.com/TimeService/[/url]这个页面有多个方法可以通过soap调用,页面上也有说明.如果用IE的浏览器还能看到此网页提供的wsdl文件.要做soap的webservice首先要了解一些关于webservice和soap的一些基本知识.下面几个网址可能会帮你快速入门.

soap教程:[url]http://www.w3school.com.cn/soap/index.asp[/url]
使用WSDL发布WebService:[url]http://blog.csdn.net/meiqingsong/archive/2005/04/04/336057.aspx[/url]

为了便于理解,我先讲下soap的大体原理:我们在iphone封装soap请求信息,发送到某个提供soap服务的服务器,如下例中我们用到的[url]http://www.Nanonull.com/TimeService/.[/url]服务器能接受和识别soap请求,当它接到请求,就根据客户端的请求情况调用服务器上的某个函数,并将函数返回结果封装成soap反馈信息发送给客户端.客户端接收到soap反馈信息后,进行解析处理,以用户能理解的形式呈现给用户.整个过程就这么简单.

好了,假设现在你已经有关于soap的基础知识(没有也没关系,看了例子,再理解就更好理解了),下面我们开始做soap的例子.

第一步,建一个Hello_SOAP项目.用IB将Hello_SOAPViewController.xib做成如下图的界面
[img]http://www.aisidechina.com/forum/attachments/month_1002/100225091078ca612f47a30308.png[/img]
然后在Hello_SOAPViewController.h中添加如下代码
[code]
@interface Hello_SOAPViewController : UIViewController
{
IBOutlet UITextField *nameInput;
IBOutlet UILabel *greeting;

NSMutableData *webData;
NSMutableString *soapResults;
NSXMLParser *xmlParser;
BOOL recordResults;
}

@property(nonatomic, retain) IBOutlet UITextField *nameInput;
@property(nonatomic, retain) IBOutlet UILabel *greeting;

@property(nonatomic, retain) NSMutableData *webData;
@property(nonatomic, retain) NSMutableString *soapResults;
@property(nonatomic, retain) NSXMLParser *xmlParser;

-(IBAction)buttonClick: (id) sender;
- (void)getOffesetUTCTimeSOAP;
[/code]
然后在Hello_SOAPViewController.xib中将两个输出口和一个动作连接好,这个不用手把手吧?
在Hello_SOAPViewController.m文件中加入以下方法 :
[code]- (void)getOffesetUTCTimeSOAP
{
recordResults = NO;
//封装soap请求消息
NSString *soapMessage = [NSString stringWithFormat:
@"\n"
"\n"
"\n"
"\n"
"%@\n"
"
\n"
"
\n"
"
\n",nameInput.text
];
NSLog(soapMessage);
//请求发送到的路径
NSURL *url = [NSURL URLWithString:@"http://www.nanonull.com/TimeService/TimeService.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];

//以下对请求信息添加属性前四句是必有的,第五句是soap信息。
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"http://www.Nanonull.com/TimeService/getOffesetUTCTime" forHTTPHeaderField:@"SOAPAction"];

[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

//请求
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

//如果连接已经建好,则初始化data
if( theConnection )
{
webData = [[NSMutableData data] retain];
}
else
{
NSLog(@"theConnection is NULL");
}


}[/code]
这个方法作用就是封装soap请求,并向服务器发送请求.
代码有注释.不重复讲解.soap并不难,难的是没有案例告诉我们怎么把其它平台的soap移植过来,这里我给出了代码,我相信对iphone开发人员的话应该能看懂了.我在下面会把此案例的源代码附上.如果自己做不出来再看我的代码.如果我这样讲您觉得不够细,那说明您的iphone开发还不是太深入,那么您应该用不到soap技术.可以飘过了.
下面的代码是接收信息并解析,显示到用户界面
[code]-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
NSLog(@"connection: didReceiveResponse:1");
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
NSLog(@"connection: didReceiveData:2");

}

//如果电脑没有连接网络,则出现此信息(不是网络服务器不通)
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"ERROR with theConenction");
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"3 DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(theXML);
[theXML release];

//重新加載xmlParser
if( xmlParser )
{
[xmlParser release];
}

xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate: self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];

[connection release];
//[webData release];
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
NSLog(@"4 parser didStarElemen: namespaceURI: attributes:");

if( [elementName isEqualToString:@"getOffesetUTCTimeResult"])
{
if(!soapResults)
{
soapResults = [[NSMutableString alloc] init];
}
recordResults = YES;
}

}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(@"5 parser: foundCharacters:");

if( recordResults )
{
[soapResults appendString: string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(@"6 parser: didEndElement:");

if( [elementName isEqualToString:@"getOffesetUTCTimeResult"])
{
recordResults = FALSE;
greeting.text = [[[NSString init]stringWithFormat:@"第%@时区的时间是: ",nameInput.text] stringByAppendingString:soapResults];
[soapResults release];
soapResults = nil;
NSLog(@"hoursOffset result");
}

}
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"-------------------start--------------");
}
- (void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"-------------------end--------------");
}[/code]
说明下:
[code]-(void)connectionDidFinishLoading:(NSURLConnection *)connection[/code]

这个方法是存储接收到的信息
[code]-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName[/code]

Friday, March 12, 2010

连连看算法(JAVA Code)






1. private boolean horizon(Point a, Point b)
2. {
3. if(a.x == b.x && a.y == b.y)//如果点击的是同一个图案,直接返回false
4. return false;
5. int x_start = a.y <= b.y ? a.y : b.y;
6. int x_end = a.y <= b.y ? b.y : a.y;
7. for(int x = x_start + 1; x < x_end; x++)//只要一个不是-1,直接返回false
8. if(map[a.x][x] != -1){
9. return false;
10. }
11. return true;
12. }












1. private boolean vertical(Point a, Point b)
2. {
3. if(a.x == b.x && a.y == b.y)
4. return false;
5. int y_start = a.x <= b.x ? a.x : b.x;
6. int y_end = a.x <= b.x ? b.x : a.x;
7. for(int y = y_start + 1; y < y_end; y++)
8. if(map[y][a.y] != -1)
9. return false;
10. return true;
11. }












1. private boolean oneCorner(Point a, Point b)
2. {
3. Point c = new Point(a.x, b.y);
4. Point d = new Point(b.x, a.y);
5. if(map[c.x][c.y] == -1)
6. {
7. boolean method1 = horizon(a, c) && vertical(b, c);
8. return method1;
9. }
10. if(map[d.x][d.y] == -1)
11. {
12. boolean method2 = vertical(a, d) && horizon(b, d);
13. return method2;
14. } else
15. {
16. return false;
17. }
18. }















1. private LinkedList scan(Point a, Point b)
2. {
3. ll = new LinkedList();
4. //Point c = new Point(a.x, b.y);
5. //Point d = new Point(b.x, a.y);
6. for(int y = a.y; y >= 0; y--)
7. if(map[a.x][y] == -1 && map[b.x][y] == -1 && vertical(new Point(a.x, y), new Point(b.x, y)))
8. ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
9.
10. for(int y = a.y; y < map.row; y++)
11. if(map[a.x][y] == -1 && map[b.x][y] == -1 && vertical(new Point(a.x, y), new Point(b.x, y)))
12. ll.add(new Line(0, new Point(a.x, y), new Point(b.x, y)));
13.
14. for(int x = a.x; x >= 0; x--)
15. if(map[x][a.y] == -1 && map[x][b.y] == -1 && horizon(new Point(x, a.y), new Point(x, b.y)))
16. ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
17.
18. for(int x = a.x; x < map.column; x++)
19. if(map[x][a.y] == -1 && map[x][b.y] == -1 && horizon(new Point(x, a.y), new Point(x, b.y)))
20. ll.add(new Line(1, new Point(x, a.y), new Point(x, b.y)));
21.
22. return ll;
23. }



1. private boolean twoCorner(Point a, Point b)
2. {
3. ll = scan(a, b);
4. if(ll.isEmpty())
5. return false;
6. for(int index = 0; index < ll.size(); index++){
7. Line line = (Line)ll.get(index);
8. if(line.direct == 1){
9. if(vertical(a, line.a) && vertical(b, line.b)){
10. return true;
11. }
12.
13. } else
14. if(horizon(a, line.a) && horizon(b, line.b)){
15. return true;
16. }
17. }
18. return false;
19. }


/**************Main Function******************/

1. public boolean checkLink(Point a,Point b){
2. if(map[a.x][a.y] != map[b.x][b.y])//如果图案不同,直接为false
3. return false;
4. if(a.x == b.x && horizon(a, b))
5. return true;
6. if(a.y == b.y && vertical(a, b))
7. return true;
8. if(oneCorner(a, b))
9. return true;
10. else
11. return twoCorner(a, b);
12. }

Thursday, March 11, 2010

NSFileHandle

NSFileHandle *myHandle = [NSFileHandle fileHandleForUpdatingAtPath:appFile];
[myHandle seekToEndOfFile];
[myHandle writeData:data];
[myHandle closeFile];




Maybe better is:
- on App startup:
NSFileHandle *myHandle = [NSFileHandle fileHandleForUpdatingAtPath:appFile];

- on log write
[myHandle seekToEndOfFile];
[myHandle writeData:data];
[myHandle synchronizeFile];

- on App shutdown
[myHandle closeFile];

LINUX 学习方法、书籍:shell+LAMP+dns+mail+proxy+programming+IDS+filewall+Kernel (转)

LINUX 学习方法、书籍:shell+LAMP+dns+mail+proxy+programming+IDS+filewall+Kernel
(http://www.linuxdiyf.com/blog/?74825/action_viewspace_itemid_2056.html)
2007-12-14 08:20:26
LINUX 学习方法、书籍:shell+LAMP+dns+mail+proxy+programming+IDS+filewall+Kernel

相信很有CUer都有这样的经历,想学习unix系统可是无从下手。其实我想说的是学习UNIX其实并不是想得那样难。

今天我就将我自己的学习方法总结一下吧,算是给广大cuer一些建议吧。

1)选择一个适合自己的的系统
对于广大CUer来说,相信大家基本上都没有自己的服务器,很多人都是在VM上跑LINUX&UNIX吧。

那么我们就要选择linux bsd 等系统而不是•AIX •Solaris 等系统。因为系统构架不同,我们常用的都是基于i686系统。如果公司的服务器可以让你拿来学习除外。

建议大家使用linux,不单是因为其开源。最主要的是相对来讲学习资料比较多。出现问题要方便解决一点儿。

2) 选择一个适合自己的的发行版
现在的发行版多多,每个版本都有每个版本的特点。但由于其于命令行,区别也不是很大,内核都一样的,软件也差不多。只不过加了一些有特色的软件罢了。
个人比较喜欢用Debian,因为其apt管理软件方便,个人觉得强于rpm。

3)  安装系统时候最好不要安装x环境,因为在一般来说服务器上都是不应该存在这样的软件的。而且这个东东容易出错。
    再者用x常会让人产生惰性。其实用命令行习惯了,感觉比GUI下还要快。

4)不要想一口吃成一个大胖子。
UNIX系统不像win那样,会玩一点小游戏,会安装一些软件就可以自称为高手了。UNIX学习是一个漫长的过程。

5)学习从先学好英文开始。
其实很多知识书里面都有,只是对于中文资料来讲相对较少。很多国外大公司都出了很多优秀的书籍。其书的质量是国内不能相比的。
所以我们要养成看原版书籍的习惯。再者如果你真的想学习unix的话,英文是必须的。因为在实际的操作中其实都是英文。当然如果你安装汉化的X,那只能说你没有接触到深层次的,X汉化的只是一个界面。
个人很反感UNIX硬要学习WINDOSW搞那样的界面。UNIX在我眼里面就只会当服务器用,所以在我的学习中不会出现什么显卡配置出错,
wine能玩什么WIN游戏的问题。

6)多试验!平时最好多用一些原码包自己编译一些软件来试验一下。
把各种所学到的东西都运用到实验之中,这才是进步的最好办法。

7)学习进程(其实就是应该怎么看书,这才是我写这文的主要目的)

学习并不是死记命令和参数。 参数那么多谁记得住啊,所以我的建议是先记得一些常用的命令和参数,在日常学习中如果要用到哪一个命令我们再去看他的manual

推荐一些比较好的书,这些书网上很多地方都可以下,GOOGLE一下就可以了


初学的时候可以看看:(如果有是刚接触到UNIX 系统的话,你可以先找一些中文资料先看一个大概 cu上多了,我就不列了)
100_LINUX_TIPS_AND_TRICKS
Linux_in_a_Nutshell_Fifth_Edition
Linux Cookbook
How.Linux.Works.What.Every.Super.User.Should.Know
Hardening_Linux
Linux Complete Command Reference

学习VI可以看:
Learning The VI Editor

学习UNIX就要学会配置一些服务
相信我吧,从最简单的vsftpd开始,使自己习惯于写conf

当学习几个月后相信大家对UNIX有所了解,那么你就可以涉足到服务器的配置上来了

可以看下面一些书籍:(LAMP组合-linux apache mysql php)
Apache_Server_2.0_Bible
Wrox.Beginning.PHP5.Apache.and.MySQL.Web.Development
Apache Cookbook
Php And Mysql For Dummies
PHP.Cookbook
Spring.into.PHP.5
Sams.MySQL.3rd.Edition.Mar.2005.eBook-LiB
MySQL.Essential.Skills.eBook-LiB
MySQL_Cookbook


上面就是建站所用到了,到后来你可以看看关于网络安全方面的
Linux.Security.Cookbook
Apache.Security
Practical.Unix.And.Internet.Security.3rd.Edition
Hack Proofing Linux(推荐一下这本书,此书要求动手较强)
系统性地讲解 建IDS及FIREWAIL
Syngress.Snort.2.1.Intrusion.Detection.Second.Edition
Sams - Linux Firewalls 3rd

通过上面的学习应该学习一下建DNS,及MTA了,这个人觉得比 建 LAMP环境要困难一点儿,但是很适用啊
建议看
OReilly DNS and BIND 5th(2006)
Pro.DNS.and.BIND
MTA(你可以理解成服务器)最好不要去学习sendmail了因为不但配置比较难而且现在已经有点儿过时了。
建议学习qmail,postfix
可以看一下:
oreilly_postfix_the_definitive_guide

建议好先学习玩dns再来学习MTA,要不很多东西会让人很头痛。

如果要想学习一下Proxy 建议看
Squid.The.Definitive.Guide

编程:我学习UNIX其实最初的原因就是因为其开源,自己可以看其原码而明白很多其上面的编程方法

建议:不要忘记shell
shell 在很多人眼里面只是脚本,总觉得能完成的事情不多,但是想是通过前面的学习已经看到了其重要性
所以想系统性地学习一下可以看看:
Regular.Expression.Pocket.Reference
Linux shell
Linux Shell scrīpting With Bash
OReilly.Learning.the.bash.Shell
Sams Publishing - unix shell programming ed3

系统编程我先推荐一本《unix环境高级编程 第二版》看其他书的时候把把这本看完了先,注意要看第二版,第一版到现在已经有十多年了,很多标准与现在已经不相同了。
此书叫做unix编程圣经级别的,相信我没错的。
这本目录已经有中文版的,不过建议看原版。

网络编程:
UNIX Network Programming Volume 1 3rd Ed

编译内核:
Understanding.The.Linux.Kernel.3Ed

当然书这么多,不可能每一本都看,大家可以选择性地看看,相信对于学习很有帮助。
我也是这样过来的。

以上都是自己的一些平时学习的一些总结,可能没有什么条理。
但希望对于大家学习有所帮助。

几个好网站:
鸟哥的linux私房菜:http://linux.vbird.org/
中国linux:http://linux.chinaunix.org
LAMP大全:http://www.lamp9.cn

Linux Study(转)

假设你是计算机科班出身,计算机系的基本课程如数据结构、操作系统、体系结构、编译原理、计算机网络你全修过
我想大概可以分为4个阶段,水平从低到高
从安装使用=>linux常用命令=>linux系统编程=>内核开发阅读内核源码
linux常用命令要学会自己编译内核,优化系统,调整参数。安装和常用命令书太多了,找本稍微详细点的就ok,其间需要学会正则表达式
系统编程推荐《高级unix环境编程》,黑话叫APUE,还有《unix网络编程》。这时候大概还需要看资料理解elf文件格式,连接器和加载器,cmu的一本教材中文名为《深入理解计算机系统》比较好
内核开发阅读内核源码阶段,从写驱动入手逐渐深入linux内核开发
参考书如下《linux device drivers》,黑话叫ldd
《linux kernel development》,黑话叫lkd
《understading the linux kernel》,黑话叫utlk
《linux源码情景分析》
这四本书为搞内核的必读书籍
最后,第三阶段和第四阶段最重动手,空言无益,光看书也不罩,不动手那些东西理解不了。

学习linux/unix编程方法的建议
建议学习路径:
首先先学学编辑器,vim, emacs什么的都行。
然后学make file文件,只要知道一点就行,这样就可以准备编程序了。
然后看看《C程序设计语言》K&R,这样呢,基本上就可以进行一般的编程了,顺便找本数据结构的书来看。
如果想学习UNIX/LINUX的编程,《APUE》绝对经典的教材,加深一下功底,学习《UNP》的第二卷。这样基本上系统方面的就可以掌握了。
然后再看Douglus E. Comer的《用TCP/IP进行网际互连》第一卷,学习一下网络的知识,再看《UNP》的第一卷,不仅学习网络编程,而且对系统编程的一些常用的技巧就很熟悉了,如果继续网络编程,建议看《TCP/IP进行网际互连》的第三卷,里面有很多关于应用协议telnet、ftp等协议的编程。
如果想写设备驱动程序,首先您的系统编程的接口比如文件、IPC等必须要熟知了,再学习《LDD》2。

对于几本经典教材的评价:
《The C Programing Language》K&R 经典的C语言程序设计教材,作者是C语言的发明者,教材内容深入浅出。虽然有点老,但是必备的一本手册,现在有时候我还常翻翻。篇幅比较小,但是每看一遍,就有一遍的收获。另外也可用谭浩强的《C语言程序设计》代替。
《Advanced Programing in Unix Envirement》 W.Richard Stevens:也是非常经典的书(废话,Stevens的书哪有不经典的!),虽然初学者就可以看,但是事实上它是《Unix Network Programing》的一本辅助资料。国内的翻译的《UNIX环境高级编程》的水平不怎么样,现在有影印版,直接读英文比读中文来得容易。
  《Unix Network Programing》W.Richard Stevens:第一卷讲BSD Socket网络编程接口和另外一种网络编程接口的,不过现在一般都用BSD Socket,所以这本书只要看大约一半多就可以了。第二卷没有设计到网络的东西,主要讲进程间通讯和Posix线程。所以看了《APUE》以后,就可以看它了,基本上系统的东西就由《APUE》和《UNP》vol2概括了。看过《UNP》以后,您就会知道系统编程的绝大部分编程技巧,即使卷一是讲网络编程的。国内是清华翻译得《Unix网络编程》,翻译者得功底也比较高,翻译地比较好。所以建议还是看中文版。
《TCP/IP祥解》一共三卷,卷一讲协议,卷二讲实现,卷三讲编程应用。我没有怎么看过,但是据说也很经典的,因为我没有时间看卷二,所以不便评价。
《用TCP/IP进行网际互连》Douglus.E.Comer 一共三卷,卷一讲原理,卷二讲实现,卷三讲高级协议。感觉上这一套要比Stevens的那一套要好,就连Stevens也不得不承认它的第一卷非常经典。事实上,第一卷即使你没有一点网络的知识,看完以后也会对网络的来龙去脉了如指掌。第一卷中还有很多习题也设计得经典和实用,因为作者本身就是一位教师,并且卷一是国外研究生的教材。习题并没有答案,留给读者思考,因为问题得答案可以让你成为一个中级的Hacker,这些问题的答案可以象Douglus索取,不过只有他只给教师卷二我没有怎么看,卷三可以作为参考手册,其中地例子也很经典。如果您看过Qterm的源代码,就会知道Qterm的telnet 实现部分大多数就是从这本书的源代码过来的。对于网络原理的书,我推荐它,而不是Stevens的《TCP/IP祥解》。
  《Operating System - Design and Implement》这个是讲操作系统的书,用Minix做的例子。作者母语不是英文,所以英文看起来比较晦涩。国内翻译的是《操作系统设计与实现》,我没看过中文版,因为翻译者是尤晋元,他翻译的《APUE》已经让我失望头顶了。读了这本书,对操作系统的底层怎么工作的就会有一个清晰的认识。
  《Linux Device Driver》2e ,为数不多的关于Linux设备驱动程序的好书。不过内容有些杂乱,如果您没有一些写驱动的经验,初次看会有些摸不着南北。国内翻译的是《Linux设备驱动程序》第二版,第一版,第二版的译者我都有很深的接触,不过总体上来说,虽然第二版翻译的有些不尽人意,但是相比第一版来说已经超出了一大截。要读这一本书,至少应该先找一些《计算机原理》《计算机体系结构》的书来马马虎虎读读,至少应该对硬件和计算机的工作过程有一些了解。

self 的用法

关于什么时间用self. , 其实是和Obj-c的存取方法有关, 不过网上很多人也都这么解答的, 那它为什么和存取方法有关? 怎么有关的? 并没有多少人回答出来. 同时关于内存管理的内容, 请大家看旺财勇士的Objective-C内存管理总结~CC专版 , 有些东西我就不多解释了.
    进入正题, 我们经常会在官方文档里看到这样的代码:
MyClass.h
[lang=objc][/lang]
@interface MyClass : NSObject {
    MyObject *myObject;
}
@property (nonatomic, retain) MyObject *myObject;
@end
[/lang]
MyClass.m
[lang=objc]
@synthesize myObject;

-(id)init{
    if(self = [super init]){
        MyObject * aMyObject = [[MyObject alloc] init];
        self.myObject = aMyObject;
        [aMyObject release];
    }
    return self;
}[/lang]
有人就问, 为什么要这么复杂的赋值? 为什么要加self. ? 直接写成self.myObject = [[MyObject alloc] init];不是也没有错么? 不加self有时好像也是正常的?

现在我们来看看内存管理的内容:

先看间接赋值的:
    1.加self.:
[lang=objc]
        MyObject * aMyObject = [[MyObject alloc] init]; //aMyObject retainCount = 1;
        self.myObject = aMyObject; //myObject retainCount = 2;
        [aMyObject release];//myObject retainCount = 1;
[/lang]
    2. 不加self.:
[lang=objc]
       MyObject * aMyObject = [[MyObject alloc] init]; //aMyObject retainCount = 1;
        myObject = aMyObject; //myObject retainCount = 1;
        [aMyObject release];//对象己经被释放
[/lang]
再看直接赋值的:
    3.加self.:
[lang=objc]
        self.myObject = [[MyObject alloc] init]; //myObject retainCount = 2;
[/lang]
    4. 不加self.:
[lang=objc]
        myObject = [[MyObject alloc] init]; //myObject retainCount = 1;
[/lang]
现在是不是有点晕, 我们先来把代码改一下, 官方的一种常见写法:

MyClass.h
[lang=objc]
@interface MyClass : NSObject {
    MyObject * _myObject;
}
@property (nonatomic, retain) MyObject *myObject;
@end
[/lang]
MyClass.m
[lang=objc]
@synthesize myObject = _myObject;
[/lang]
OK, 你现在再试下, 如果你用self._myObject = aMyObject; 或者 myObject = aMyObject; 你会得到一个错误, 为什么呢, 这里就是和Obj-c的存取方法有关了. 说白了很简单 , 大家都知道, @property (nonatomic, retain) MyObject *myObject; 是为一个属性设置存取方法, 只是平时我们用的方法名和属性名是一样的,现在你把它写成不同的名字, 就会很清楚了. _myObject是属性本身, myObject是存取方法名.

现在我们知道self.是访问属性的存取方法了, 那存取方法又怎么工作的? self.myObject = [[MyObject alloc] init]; 为什么会有内存泄露?
关于nonatomic我不多解释了, 它不是我要讲的重点, 而且我也没完全搞清楚, 不误导大家. 我只说assign, retain ,copy.
get方法是:
[lang=objc]
-(MyObject*)myObject{
    return _myObject;
}
[/lang]
Set方法是:
[lang=objc]
// assign
-(void)setMyObject:(id)newValue{
    _myObject = newValue;
}
// retain
-(void)setMyObject:(id)newValue{
    if (_myObject != newValue) {
        [_myObject release];
        _myObject = [newValue retain];
    }  
}
// copy
-(void)setMyObject:(id)newValue{
    if (_myObject != newValue) {
        [_myObject release];
        _myObject = [newValue copy];
    }
}
[/lang]
其实这些方法里还有别的内容, 并不只是这些. 而且这些方法可以被重写. 比如你写一个
[lang=objc]
-(MyObject*)myObject{
    
    return _myObject;
}
[/lang]
放在你的类里, 你调用self.myObject时(不要把它放在等号左边, 那会调用get方法)就会调用这个方法.

这里多说一句, @property 是为你设置存取方法, 和你的属性无关, 你可以只写一句
[lang=objc]
@property (readonly) NSString *name;
[/lang]
在你的类里实现
[lang=objc]
-(NSString*)name{
    NSLog(@"name");
    return @"MyClass";
}
[/lang]
同样可以用self.name调用.

现在回头说说我们开始的那四个赋值, 当不用self.的时候,  那句话只是一般的赋值, 把一个指针赋给另一个指针, 不会对分配的内存有任何影响, 所以2中不要最后[aMyObject release];这句话和4是一回事. 这里就不多说了.我们看看1和3,
当调用setMyObject:方法时, 对newValue 做了一次retain操作, 我们必须把原来的newValue释放掉, 不然就会内存泄露, 在1里, 我们有个aMyObject可以用来释放, 在3里, 我们无法释放它, 所以, 在3里, 我们会多出来一个retainCount. 内存泄露了.

说了这么多, 我只想让大家清楚, 什么是调用属性本身, 什么是调用存取方法. 怎么样才能避免内存泄露, 而且, 以上例子里是在自己类里的调用, 如果这个类被别的类调用时, 更要注意一些,

顺便说一下, 如果你想在其它类访问对象属性, 而不是通过存取方法, 你可以用myClass -> myObject来访问, 这样是直接访问对象本身, 不过你先要把myObject设成@public. 但这个是官方不提倡的,

Wednesday, March 10, 2010

金融学习(转)

1.学习
(1)入门书籍:< Finance >, Zvi Bodie, Robert C. Merton,框架非常清晰
(2)中级教材a. Investments:< Essentials of Investments >, Zvi Bodie, Alex Kane, Alan J. Marcus.< Investments >, William F.Sharpe, Gordon J.Alexander, Jeffrey V.Bailey第一本书行文更流畅易懂,第二本较学术化,但两者选一即可。在阅读时不但应该学习规范市场的运作,更应该想想中国市场到底因为哪些原因使得如此的无效率。在理论和实际中反复的来来回回,可以使人更好的理解两者。b. Corporate Finance< Principles of Corporate Finance >, Richard A.Brealey, Stewart C.Myers< Corporate Finance >, Stephen A. Ross, Randolph W. Westerfield, Jeffrey F. Jaffe第一本通俗些,例子写的非常漂亮,第二本学术化色彩较浓,也是两者选一即可。需要了解简单的会计知识,仅借贷和资产负债表等基础即可。c. Derivatives< Options, Futures and other Derivatives >, John C. Hull如果简单的了解,a中任何一本书相关的部分就足够了。
(3)数理化的教材< The Econometrics of Financial Markets >,John Y. Campbell, Andrew W. Lo, A.Craig MacKinlay全面介绍了金融学中常用的计量方法。

2.研究
(1)了解理论发展脉络掌握了经济学基本工具(建模、计量),再有金融学相关的知识,就应该开始做研究了。强烈推荐在这一阶段先看下面这本金融思想史方面的书:< Capital Ideas : the Improbable Origins of Modern Wall Street >, Peter L. Bernstein.此书用一个个扣人心弦的故事,简洁、流畅而完整的叙述了金融理论是如何随着金融市场的发展而成长起来的,启迪初学者如何观察现象、发现问题、简化变量,完美的展示了金融市场奔腾不息的力量和金融理论的深邃迷人的美感。
(2)专题研究:从问题入手在学习理论的时候,总会发现一些既有理论难以解释的问题,顺着这些问题展开研究,阅读相关的书籍、论文,和同学、师长以及有实践经验的人讨论,这样对理论的理解比较深,能够看到理论是如何抽象实际的,假设是如何决定结论的。强烈反对先划定一个领域,看完一本“经典”教科书后再看另一本“经典”,不断预备知识的学习方式,因为知识是永远“预备”不完的,即使“预备”完毕了,也很可能只会在一个框架下思考,丧失了发现问题的能力。研究的时候要把思路放宽,尽量早的去和同学师长讨论,一个人冥思苦想很可能在一个死结上纠缠,他人的建议、经验和相关资源能够帮你打开思路。例如,自己当时想解释为什么中国的小股民明知权利得不到保护也要持有股票,由于开始读的都是教科书,而这些书都是基于Efficient Market Hypothesis (EMH)的,自己改什么风险偏好的效用函数、设定投资机会限制,不是结论不对,就是太牵强,总让自己很不舒服。直到有一天和一个师兄讨论,他建议我去看看行为金融(Behavior Finance)方面的资料,我才发现自己已经太久的被束缚在EMH里,而且浑然不觉。(建议阅读:< Inefficient markets : an introduction to behavioral finance>,Andrei Shleifer)
(3)保持开放的思想,研究新的领域在一个领域做久了,总会习惯思考相关的问题,虽然我们的确需要在某个领域沉淀很久才会有所贡献,但不能在不知不觉中限制自己思考的领域。建议时常浏览如下网页看看现在的研究在做什么:Journal of Finance: http://www.afajof.org/Journal of Financal Economics : http://jfe.rochester.edu/jfe.htmNBER :www.nber.org正式发表的文章已经比较慢了,有时间应该去各大名校金融系的网页上去看working paper.
(4)网络资源统计年报:http://www.gse.pku.edu.cn/dataset/index.htm中国资讯行:http://www.bjinfobank.com国外数据:www.economagic.comwww.economy.com/freelunch

()实务

资源学习和研究的努力可以保证一个人在学校取得较有意义的研究成果,但是很现实的,绝大部分人都需要到社会上来工作,承担自己的责任。因此,了解现实的情况,知道一些被理论滤去但却在实践中非常重要的变量是很重要的,下面的一些资源可供参考。

1.书籍

(1) 历史部分< Manias, Panics, and Crashes : a History of Financial Crises >,Charles P. Kindleberger金融危机是金融市场永恒的话题,而且历史不断的上演同样的故事。< The House of Morgan: An American Banking Dynasty and the Rise of Modern Finance >,Chernow, Ron(中译本:《摩根财团:美国一代银行王朝和现代金融业的崛起》,金立群校译,中国财政经济出版社)< Wriston : Walter Wriston, Citibank and the Rise and Fall of American Financial Supremacy >,Phillip L. Zweig.(中译本:《沃尔特瑞斯顿与花旗银行:美国金融霸权的兴衰》,海南出版社)每一个金融巨子都是时代的产物,看看他们如何把握历史时机,如何面对巨大的危难。《胡雪岩》(高阳)了解中国社会的商业环境。
(2)投资部分< One up on Wall Street : how to use what you already know to make money in the market >, Peter Lynch with John Rothchild强调基本面分析,对生活的观察,Peter Lynch的其他书也可以。< The Alchemy of finance : reading the mind of the market > or< Open society : reforming global capitalism >,George Soros(中译本:《金融炼金术》,海南出版社;《开放社会: 改革全球资本主义》商务印书馆)阅读其中任一本都可以了解索罗斯的思想,只是第一本书后一部分非常技术性。个人认为其书有价值之处在于用解析主义的方法论分析金融市场,在书中称其为反身性,这是与经济学实证主义本质上不同的思维方式。< Valuation : measuring and managing the value of companies > McKinsey & Company, Inc, Tom Copeland, Tim Koller, Jack Murrin.介绍了实用的估值方法
(3)银行《日本金融败战》,(日)竹内宏著,彭晋璋译,中国发展出版社 1999一个精彩的案例,反思了大而不强的日本银行的困境和错误的改革思路。《复合萧条论:泡沫经济的经济对策》,(日)宫崎义一,陆华生译,中国人民大学出版社2000介绍了日本80年代泡沫经济产生、发展和破灭的全过程,对于正在走向金融自由化的中国有重要借鉴意义。< The Bank Credit Analysis Handbook : a guide for analysts, bankers and investors >, Jonathan Golin对银行较为全面的评估手册。< Microeconomics of Banking >, Xavier Freixas, Jean-Charles Rochet< FinancialIntermedraices >, Mervyn K.Lewis对银行的经济学分析,很好的学术性书籍。

2.网络资源推荐了很多国外网站,毕竟我们是在一个急速全球化的时代之中。

杂志:

《财经》 :http://www.caijing.com.cn/(国内最好的财经期刊)
《比较》 :http://www.bijiao.org(学术性,收费)
Financial Analysts Journal : http://www.aimrpubs.org/faj/home.htmlTime:http://www.time.comEconomist : http://www.economist.comBusiness Week : http://www.businessweek.com/(推荐订阅其免费新闻)Fortune : http://www.fortune.com/The Banker : http://www.thebanker.com/Foreign Affairs : http://www.foreignaffairs.org/

报纸:
《二十一世纪经济报导》:http://www.nanfangdaily.com.cn/jjFinancial Times :www.ft.com (15天免费)Wall Street Journal :www.wsj.com (14天免费)The New York Times : http://www.nytimes.com/(推荐订阅其免费新闻)

机构:
人民银行:http://www.pbc.gov.cn/
银监会:http://www.cbrc.gov.cn/
证监会:http://www.csrc.gov.cn
保监会:http://www.circ.gov.cn/
发改委:http://www.sdpc.gov.cn/
财政部:http://www.mof.gov.cn
国资委:http://www.sasac.gov.cn
商务部:http://www.mofcom.gov.cn/
国家统计局:http://www.stats.gov.cn/
上交所:http://www.sse.com.cn
深交所:http://www.szse.cn
世界银行:http://www.worldbank.org/IMF : http://www.imf.org/
美联储 : http://www.federalreserve.gov/
欧洲央行 : http://www.ecb.intBank for International Settlements :http://www.bis.org

了解这些制定游戏规则的机构除了以上资源以外,还可以看一些涉及经济金融运作的电影,例如< Wall Street > (内幕*纵)、< Other People’s Money >(兼并重组)、《胡雪岩》(政治经济依存)等

如何在你的应用程序中使用Openfeint (在线排行 成就系统 挑战功能) 《转》

游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能,这样的好处有很多,比较特别的有两点。
1. 不用考虑虚拟键盘调用后进行的用户名输入,我就是觉得做个虚拟键盘输入名字做rank让我很崩溃所以才出此“下策”
2. 即时监控用户登录情况,随着每个用户的成绩提交,可以大致知道自己的游戏有多少用户。

目前我们的选择有两个,一个是plus+ ,本来我想用它,因为我觉得plus+这个logo和颜色跟我的游戏内容比较合,奈何落花有意流水无情,我申请完等了一个星期后被他否掉 ,在这样半被迫的情况下,我选择了openfeint,并且深深为它的功能所折服,不敢专美,与各位有需要的朋友分享。

注意,我这里说的情况是在原生程序中使用openfeint,u3d的引擎的不在我的讨论之列。另外我是web程序员出身,很多描述也许不够专业和精确,请各位指出及海涵。

首先,在官网注册为开发者,建立一个项目,你会得到一个项目的client id(用于提问),一个产品编号跟一个密钥,这将放置于程序中,注意不要输错,我曾经因为少粘贴了一位密钥
结果载入程序界面老是报莫名的错误。后来还是经过Fwish版主的提醒(他也曾经遇到一样的报错),才发现问题所在。
在官网下载SDK,察看它包里的readme,注意看 Building OpenFeint With Your Project 部分
一步一步照做,注意第九步 9. You must have a prefix header. It must have the following line: #import "OpenFeintPrefix.pch"
这个是加在 项目名_Prefix.pch这个文件的最后就可以了。
一般来说,编译出4000多个错的话,多半是这里没加。另外要将所有#import到openfeint头文件的.m文件的扩展名通通改为.mm,以实现objectC和C++的混合编译。

完成以上步骤后,可以尝试编译一下,能够顺利编译就没有问题了。

接下来要做的可以在openfeint附带的sample里面看到,它的sample写得还是比较仔细的,不过它用的是UIKit和nib文件,所以开发游戏的还要根据自己的引擎做一些修改。

首先,在"项目名AppDelegate.mm"的文件里加入openfeint的载入定义部分,以让其在每次程序load完以后就起作用。
- (void) startup
{
ofDelegate = [MyOFDelegate new];
//ofNotificationDelegate = [SampleOFNotificationDelegate new];
//ofChallengeDelegate = [SampleOFChallengeDelegate new];
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: UIDeviceOrientationPortrait],
OpenFeintSettingDashboardOrientation,@"ArithMaster",
OpenFeintSettingShortDisplayName,
[NSNumber numberWithBool:YES],
OpenFeintSettingEnablePushNotifications,
[NSNumber numberWithBool:NO],
OpenFeintSettingDisableUserGeneratedContent,nil];
ofChallengeDelegate = [MyChallengeDelegate new];
OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate
andChallengeDelegate:ofChallengeDelegate
andNotificationDelegate:nil];
//OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
[OpenFeint initializeWithProductKey:@"这里输入key"
andSecret:@"这里输入密钥"
andDisplayName:@"Airthmetic Master"
andSettings:settings // see OpenFeintSettings.h
andDelegates:delegates]; // see OFDelegatesContainer.h
}

代码中ofDelegate和ofChallengeDelegate两个代理分别对应于OF的启动以及challenge模式的启动。
这两个类的具体写法可以参考sample中的例子,我基本上照抄了。

这样做完以后,可以通过执行 [OpenFeint launchDashboard]来进入OF界面,官方文档中建议这个可以作为一个按钮的绑定方法来实现。

另外重要的文档就在开发者界面里面指定功能里,点击问号会进入帮助界面,会告诉你功能相关头文件和基本的用法,注意调用方法的时候需要察看一下是否包含了带有该方法的头文件。

接下来我说说怎么提交成绩,很简单,就一句 [OFHighScoreService setHighScore: score forLeaderboard:@"排行榜id" onSuccess:OFDelegate() onFailure:OFDelegate()];
这个排行榜id是通过在leaderboard里面新建leaderboard取得的,在它的配置选项里可以选择成绩按照降序还是升序排列。一般都认为成绩是降序的,其实也不其然,比如我的《算术大师》,时间越短排行越高,就要按照升序排列。

至于提交成就也就一句 [OFAchievementService unlockAchievement: @"成就id" onSuccess: OFDelegate() onFailure: OFDelegate()];
这些成就可以在任何条件判断后执行,比如我指定了一个成就在成绩低于12秒的时候触发,就可以写 if(costsecond < 12) 触发成就 ,可以放心的是在你解锁了该成就以后,再次达到成就触发条件也不会重复触发成就。

以上两个都是OF的基本功能,使用也相对简单,我接下来要说的是高级功能里面的challenge,我为这个折腾了两个晚上,苦于资料稀缺,无人可问,终于攻克。
challenge就是挑战功能,我的理解是它其实是一种延时对战机制,用户A在完成了指定的游戏以后,可以将游戏过程数据和结果打包传输到OF的服务器上,然后你的被挑战者从服务器上下载这些数据,以跟你同样的条件进行游戏,并且在最后跟你的游戏成绩比较,这样就完成了一次挑战的过程。大家或许也想到了,在《算术大师》里,这种机制跟游戏的相性天然吻合,我的实现是把“被挑战者下载数据以后做完题目跟挑战者比较”这个过程当成两个西部牛仔的对决,谁速度更快,谁就能够打落对方的帽子。OF的文档里提到,这个同样适用于赛车游戏的场合,挑战者的数据可以作为一辆幽灵车显示在被挑战者的画面中,可以想见,被挑战者更加不允许犯错,所以还是能够增加游戏的乐趣和对抗程度的。

下面说说代码,首先是发送挑战,这个相对简单,直接上代码吧
- (void)_sendChallenge
{
ChallengeData data;

data.score = score; //给挑战数据赋值

NSData* challengeData = [NSData dataWithBytes:(void const*)&data length:sizeof(ChallengeData)]; //这句对我来说比较深奥了,只有敬畏地照抄了


[OFChallengeService
displaySendChallengeModal:@"挑战编号"
challengeText:[NSString stringWithFormat:@"my score is %d,come on!", score]
challengeData:challengeData];
}



- (void)challenge:(id)sender{

if ([OpenFeint hasUserApprovedFeint])
{
[self _sendChallenge];
}
else
{
OFDelegate nilDelegate;
OFDelegate sendChallengeDelegate(self, @selector(_sendChallenge));
[OpenFeint presentUserFeintApprovalModal:sendChallengeDelegate deniedDelegate:nilDelegate];
}
}

千万注意!根据我的实测,挑战数据似乎是C++的变量比较不会出问题,我用NSString,NSMutableString结果在打包上传,下载解包后变成了空值,我熬的两个晚上有一个多晚上都在搞这个,结果用了C++的数组,立马就没事情了,所以,可能打包进去的数据需要类似这样的处理data.leftnum=[leftnum objectAtIndex:i] intValue];


challenge的delegate,主要是在这个函数里处理
- (void)userLaunchedChallenge:(OFChallengeToUser*)challengeToLaunch withChallengeData:(NSData*)challengeData
前面一个参数里面有挑战的名称,用户等信息,后面一个NSData里面则是完整的游戏过程数据。
这个只要按照sample里照做就可以了。设置完成后,用户在openfeint内接受挑战后将以这个delegate为入口进行后续的游戏过程处理。

最后是挑战结果处理,一般就是写个方法判断输赢平,然后设置两个回调方法
OFDelegate success(self, @selector(_submittedCompletedChallenge));
OFDelegate failure(self, @selector(_failedSubmittingCompletedChallenge));
[OFChallengeService
submitChallengeResult:challenge.resourceId
result:challenge.result
resultDescription:[NSString stringWithFormat:@"my score is %d,see you next time!", correctnum]
onSuccess:success
onFailure:failure];
我建议在_submittedCompletedChallenge不要回传数据,似乎要按照传过来的数据的格式才行,否则会出错,而回传数据只有一种情况需要用到:就是被挑战者反复尝试挑战挑战者。

challenge的适用大致就是如此了,不解的话,建议反复研究OF自带的sample,另外挑战模式的测试需要用户注册两个帐户通过在OF的界面下切换来调试,当然,一模拟器一设备是最理想的。

有一些挑战相关的数据,都是可以从它传给delegate的两个参数里取得的,比如我在游戏里设置了一个成就,就是在"little Cocoa"发出的挑战中打败little Cocoa,则能获得游戏中最大的一个成就:超越开发者,这就需要判断传过来的用户名,通过对OF的源码的研究,我以这样的方式取得了用户名:[challenge.challenge.challenger name] ,当时觉得自己很牛逼,哈哈。

以上大致就是我在使用openfeint过程中的一点心得,如果有问题的话请向我提出,如果知道的话,我会尽量解答。
另外OF其实提供了很完备的社区功能,你可以在系统里面发布公告,跟你的用户通过游戏内置的论坛进行交流,发pm给你的用户,这些原本需要复杂代码实现的功能都已经由其替你实现。所以确实能够让你的游戏从一个单机游戏进入多人游戏的世界,从何在乐趣上进步一个台阶。
最后我用一句xbox的口号结束这个教程,这也被写在了我游戏的loading页面:Game Experience may change during online play via openfeint !

Monday, March 8, 2010

25 Ways to Promote an iPhone Application

Are you a programmer who developed an iPhone app which you think will be the next big hit in Apple’s iPhone App Store? If you are, you may already be thinking about how you can market the application that you developed. To help you out, here is a quick look at the top 25 ways that you can effectively market an iPhone application:

1. Work on getting included in the list of the top 100 apps in the iPhone App Store.尽量争取进入app store的top 100。

2. Make sure that you have a unique name for the iPhone app that you have so that your program will easily get noticed at the iPhone App Store itself, as well as in Google searches. Better yet, include your brand name when marketing the iPhone app that you developed.确保有个独一无二能引起苹果兴趣的应用名称,最好加上公司名或品牌名。

3. Do your homework and check on what the competition has to offer. Make sure that the iPhone app that you have has a feature or characteristic that will make it stand out from the rest.要有自己的竞争优势才能脱颖而出。

4. Publicize your iPhone app through profiling websites like AppShouter.com, AppStoreApps.com, AppSafari, AppRate and AppShopper.在苹果的应用推广网站上宣传自己的应用。

5. Get your iPhone app included in the application review sites on the net.让你的应用出现在一些应用评测网站上。

6. Create a fan page for your iPhone app on Facebook and promote the application from there.在Facebook上创建一个粉丝页面进行推广。

7. In MySpace, use the bulletin features to send out mass bulletins to the subscribers of your page and any groups that you might have joined.运用MySpace的公告特色向你页面的订阅者以及可能加入的群发送大量公告。

8. Create a blog and use it as a primary marketing tool for your iPhone app.创建一个博客,并将它作为主要的营销工具。

9. Create a trial version of the iPhone app that you developed to test the waters before launching the product full-blast.在全面发行之前,先做一个测试版进行试水。

10. Invest in buying a domain name for the iPhone app that you have to increase your rankings in Google’s natural search.投资性地为你的应用购买一个域名,这样可以上升google搜索里的排名。

11. Work on your website – make sure that the web content is well-written, post clear screenshots and videos of exactly how the iPhone app can be used.建立好自己的网站,确保网页图文并茂,截图视频清晰可用。

12. Use Google AdWords to get the word out and generate traffic to your site.使用google广告词能为你的网站带来流量。

13. Focus your marketing strategy on the benefits that a mobile phone user can get to enjoy by taking advantage of your iPhone app. 关注使用者能从你的应用中获得什么。

14. Once you have already conquered the US market, think about branching out to other markets like Germany, Australia and the UK – other countries which also have a huge number of iPhone users.一旦你占领美国市场,就可以考虑进入其他市场了,如德国,澳大利亚和英国,这些国家也有很多iphone使用者。

15. Appropriately price the iPhone app that you developed.给你的应用定一个合适的价格。

16. Have a press release written for your iPhone app and distribute it to highly targeted media outlets.让主流媒体为你的应用做一个新闻发布。

17. Use the AddThis button to promote your iPhone app online for Facebook, MySpace, Digg, LinkedIn, Blogger and other similar sites. 在Facebook, MySpace, Digg, LinkedIn, Blogger等类似网站上做广告。

18. Participate in online forums which are targeted towards the iPhone apps users.活跃于iphone应用使用者的论坛。

19. Use e-mail marketing to send out highly targeted messages to prospect buyers.使用电子邮件对潜在买家进行推销。

20. Twitter away! Make sure that within the iPhone app that you developed, there is a Twitter update feature so that you won’t be left behind with what the rest of the micro-blogging world is up to.使用twitter!

21. In all the e-mail messages that you are sending out, make sure that there is a signature line contained in all of your e-mail messages.在你发出的邮件中确保每封都有签名档。

22. Another popular website that you can use to promote your iPhone app is YouTube, where you can post a video of exactly how the program can be used.在YouTube上传视频。

23. Submit an article about your iPhone app at sites like Digg.com which online users can Digg in turn.在Digg这类的网站上写关于你的应用的文章。

24. Work with a business which has a similar market as yours which is not necessarily a direct competitor, so that your iPhone app together with their own brand can be promoted.与具有类似市场但无直接竞争关系的公司合作,这样能借他们的品牌推广你的应用。

25. Expand your network through word of mouth by telling your friends, colleagues, neighbors and everybody else using an iPhone about just how awesome the application that you developed is!拓展人际网,告诉同事、朋友等人你的应用有多棒,充分发挥口头推荐的优势。

Thursday, March 4, 2010

NH, KDH 格式的文件转化为 pdf或者word格式的文件

方法一:
首先到中国知网(www.cnki.net) 下载CAJViewer阅读器,安装CAJViewer阅读器软件。运行CAJViewer阅读器并点击“文件”打开.CAJ、.NH、.KDH等格式文 件。接下来选择“文件→打印”菜单,在打开的“打印”设置窗口中将“打印机”栏中的“名称”设置为“Microsoft Office Document Image Writer”,确认后将.CAJ、.NH、.KDH等格式文件输出为MDI格式的虚拟打印文件。

(如果 你在“名称”设置的下拉列表中没有找到“Microsoft Office Document Image Writer”项,那证明你在安装Office 2003的时候没有安装该组件,请使用Office 2003安装光盘中的“添加/删除组件”更新安装该组件。)

运行Microsoft Office Document Imaging,并利用它来打开刚才保存的MDI文件,选择“工具→将文本发送到Word”菜单,并在弹出的窗口中勾选“在输出时保持图片版式不变”,确 认后系统提示“必须在执行此操作前重新运行OCR。这可能需要一些时间”,不用管它,点确认即可。

(目前,包括此工具在内的所有软件对PDF转DOC的识别率都不是特别完美,而且转换后会丢失原来的排版格式,所以大家在转换后还需要手工对其进行后期排版和校对工作。)

方法二:
首先用CAJViewer7.02版本阅读器打开nh文件,在你当前打开页的左上方有个保存为图片的按钮

, 把当前页面保存为图片。然后下载安装一个汉王6.0,安装好后打开。注意,此软件安装好后没有快捷方式,需要按照下面的步骤打开:开始--程序--汉王 ocr6.0--汉王ocr6.0.打开后按照下面的操作就可以识别图片,转换成文字。文件--打开图像--识别--开始识别--输出--到指定格式文 件,保存为txt文件就可以了。现在打开刚刚保存的文件,是不是看见文字转换好了!

方法三:

1、从CAJ格式的文件中提取文本前需要做好以下准备工作,安装CAJViewer7.02版的CAJ浏览器软件(系统中一定要有Office2003或者是office2007 办公软件) ; 2、从网上下载CAJ格式的资料文件保存到本地硬盘上。 3、启动CAJViewer浏览器程序,用CAJViewer7.02打开刚才保存的CAJ格式的文件。 4、(1)用CAJViewer7.02打开caj 文件;(2)单击“选择图像”按钮,然后在每页的左右两边分区域选取文字(如图:红色区域内);(3)再在选取区域内,单击右键,右键选击“文字识別”。

Dlog of Objective-C

// Prefix header for all source files of the 'Avego' target in the 'Avego' project
//

#import

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif

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

#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);

#ifdef __OBJC__
#import
#import
#import
#endif

Multiple Arguments Objective-C

Side note: The @ symbol at the front of @”Testing” string is convenience method that converts the given string to an NSString object, which in the case of the setStr method, is the required type for the parameter.

Multiple Arguments
Taking this another step further, we can pass multiple arguments along with our message. The message below takes three arguments, a string, date and integer. Sometimes it easier to read the method aloud to get this jist of what’s up. In this case, “pass a message to the ptr receiver that sets a string, and a date and an integer.”

[ptr setStr:@"A new test..." andDate:[NSDate date] andInteger:99];


Here is how we define the message in the interface file:

-(void) setStr:(NSString *)str andDate:(NSDate *)date andInteger:(int)x;


And here is the implementation of the setStr() method which accepts three arguments:

-(void) setStr:(NSString *)strInput andDate:(NSDate *)dateInput
andInteger:(int)xInput
{
[self setStr:strInput];
[self setDate:dateInput];
[self setX:xInput];
}