本文面向已有其它语言(如Java,C,PHP,Javascript)编程经验的iOS开发初学者,初衷在于让个人同事一小时内了解如何开始开发iOS App,学习目标包括:php
本文不包含任何高级的iOS开发知识,已学会iOS开发的同窗不要看,看完这篇文章学会了的同窗也不用再看了。html
有过脚本开发经验的人(如Javascript,PHP,Shell)在刚开始学习iOS开发的时候,会以为iOS开发的学习曲线比脚本语言要高,是的,这种感受是对的。由于学iOS开发,不只是学习一门新语言,它包括:java
初学脚本语言一般不会来绘制图形界面、与人交互,iOS若是不作图形界面,像脚本语言同样处理文本操做数据库,就没啥意思了。linux
因此,过去我写别的新手入门教程,一般都是写《XXX入门15分钟教程》,而iOS就要花数倍的时间来写了。ios
作iOS开发必定要有苹果的软件环境:Mac OS操做系统、Objective-C编译器、设备模拟器等,开发工具倒不必定要用Xcode,只要是个源代码编辑工具就行(vim都行,只是没Xcode那么多功能)。git
拥有Mac OS环境最简单的方法是找一台苹果电脑,包括iMac, MacBook Pro, MacBook Air, Mac Mini,但不包括苹果的移动设备(iPod Touch, iPhone, iPad, iPad Mini,它们运行的是iOS系统,不是Mac OS),苹果电脑在出厂的时候就会预装Mac OS,目前最新版本是Mac OS X 10.8,主流的版本还有Mac OS X 10.六、Max OS X 10.7。程序员
若是囊中羞涩,能够借一台,或者上淘宝买个二手的。github
提到iOS开发入门,彷佛没办法不说黑苹果。所谓黑苹果,就是把Mac OS改造后安装在非苹果的硬件上,这是违反DMCA法案的,黑苹果的更多资料,能够在维基上找到web
苹果电脑价格高,国内软件开发者生存压力大,因此黑苹果在国内也有一些真实的存在,国外固然也有啦。objective-c
黑苹果基本能够胜任iOS开发,但有一些问题:
上面这些虽然不会直接影响Xcode写代码、模拟器测试,但写着写着想上网查个东西的时候,safari不能翻页,确实挺影响心情的。因此,钱包容许的前提下,仍是搞个苹果电脑省心一些。
Xcode能够在苹果官网免费下载:Xcode下载地址
安装Xcode时会自动安装iOS SDK和模拟器。
这么强大的IDE竟然是免费的,仍是挺让人开心的。
学一门新软件开发技能,可以第一时间作出一个可运行的产品很是重要,有助于给本身正面激励,我上大学的时候,有不少次想学一门新语言,每每花了半个月,还沉浸在数据类型和语法字典里,连第一个Hello World都没作出来。
这一次,就让咱们从改一个现成的应用开始吧。
首先,咱们从苹果开发者中心下载一个示例代码回来。我选了ToolBarSearch。
在本文档的末尾,还有一些其它的网址能够下载开源iOS产品或者代码段,但我试了一下,仍是Apple Sample Code最容易成功。
下载回来的zip文件最好保存在"下载"或者"文稿"目录里,由于在Mac OS 10.8之前,有些目录(例如/var/private/tmp)在Finder中是看不到的,要经过Finder的“前往 > 前往文件夹”功能才能进入。
有三种方式能够打开一个iOS Project
打开Finder,进入刚刚下载解压的ToolBarSearch目录,找到ToolBarSearch.Xcodeproj文件,双击之,Xcode会自动启动,并打开这个项目
在Xcode没启动的状况下(若是Xcode已经启动了,就先按Command Q退出),启动Xcode,会弹出“Welcome to Xcode”的欢迎页,点击左下角的“Open Other”按钮,找到ToolBarSearch目录,双击ToolBarSearch目录,或者双击ToolBarSearch.Xcodeproj文件均可以
若是Xcode处于打开状态,能够点击其菜单栏的File -> Open,或者File -> Open Recent,而后再选择要打开的项目
在Mac OS 10.8之前,有些目录(例如/var/private/tmp),在Finder和Xcode的File > Open对话框中,点击鼠标是找不到的,这时候就要经过命令行终端来打开了。
打开终端,执行:
cd /ToolBarSearch的父目录/ToolBarSearch open -a Xcode
open -a是mac os的系统命令,除了iOS项目,别的项目也能够这样打开。
点击Xcode左上角的Run按钮(或者同时按下Comman和R键),Xcode会编译源码并在模拟器中运行这个应用。
编译成功会在屏幕上淡淡地显示“Build Succeeded”。反之,失败就显示“Build Failed”且不启动模拟器。
在模拟器上看到“Performed search using…”了吧,下面咱们改掉它。
在Xcode左上角的Run按钮下方,有一排小按钮,从左到右第三个是一个放大镜图标,鼠标移上去会显示“Show the Search Navigator”,点一下它,打开搜索界面,在它下方出现的Find输入框中输入“performed”
搜索结果只有一条:ToolbarSearchViewController.m,点文件名下方被高亮的“Performed”字串,右侧代码编辑区会自动打开这个文件,并滚动屏幕,使包含“Performed”的这一行出如今编辑区的中间。
修改双引号里的字串,随便改为啥,而后按“Command S”保存。
固然,这些操做,你也能够在终端下经过grep和vim完成。
按Command R运行,看看,是否是看到效果啦?
是的,修改一个应用就这么简单。
Objective-C是苹果应用软件(包括苹果电脑上的Mac OS App和移动设备上的iOS App)的开发语言。它是一种面向对象的编程语言。
苹果公司还提供了一个软件,叫Interface Builder,简称IB,用于可视化的界面制做,就像用Dreamweaver作网页,或者像Visual Basic作桌面软件同样。后来IB就整合进了Xcode,成了Xcode的一部分。这篇文档不讲IB,只讲Objective-C,由于:
Objective-C扩展了ANSI C,是C的超集,也就是说:
除了面向对象有语法是SmallTalk风格的(下面会讲到),其它非面向对象的语法、数据类型,与C彻底相同,因此本文就再也不赘述。 来看一个经典的Hello World示例吧:
#import <Foundation/Foundation.h> int main(int argc, char *argv[]){ @autoreleasepool{ NSLog(@"Hello World!"); } return 0; }
是否是仿佛穿越回了大一学习C语言的时代,看起来和C几乎没有区别,是吧?是的,由于还没用到它的面向对象特性,哈哈!
Objective-C的面向对象语法源自SmallTalk,消息传递(Message Passing)风格。在源码风格方面,这是它与C Family语言(包括C/C++、Java、PHP)差异最大的地方。
在Java、C++世界,咱们调用一个对象的某方法,在Objective-C里,这称做给类型发送一个消息,这可不只仅是文字游戏,他们的技术细节也是不一样的。
在Java里,对象和方法关系很是严格,一个方法必须属于一个类/对象,不然编译是要报错的。而在Objective-C里,类型和消息的关系比较松散,消息处理到运行时(runtime)才会动态决定,给类型发送一个它没法处理的消息,也只会抛出一个异常,而不会挂掉。
[obj undefinedMethod];
在代码里调用没定义的方法(这是Java世界的习惯说法啊,专业的叫法是,给obj对象传递它没法处理的消息),Xcode会警告,但编译能成功,运行的时候会出错。它会输出这样一个错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject undefinedMethod]: unrecognized selector sent to instance 0x8871710'
Objective-C中一些面向对象的概念,也能够在Java中找到相似的实现(只能说是相似,不是彻底相同),个人读者基本都是Java和PHP程序员,我会在下文中尽可能用Java的概念来类比。
GoogleCode上有人整理了Java和Objective-C的概念、数据类型对应表,参见这里
Objective-C里有字符串是由双引号包裹,并在引号前加一个@符号,例如:
title = @"Hello"; if(title == @"hello") {}
PHP程序员要注意,在这里不能用单引号,即便只有一个字符也不能用。Objective-C与Java、C同样,双引号表示字符串。
前文述及,不涉及面向对象时,它和C是彻底同样的。如下是几个函数调用的示例:
startedBlock();
NSLog(@"decrypted string: %@", str); CGRectMake(0,0,0,0);
[obj method];
对应的Java版本
obj.method();
[counter increase:1];
对应的Java版本
counter.increase(1);
对C Family程序员来讲,这是最难接受的,最反人类的:
- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue {...} //定义方法 [myObj setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; //调用方法
对应的Java版
public void setColorToRedGreenBlue(float red, float green, float blue) {...} myObj.setColorToRedGreenBlue(1.0, 0.8, 0.2);
UINavigationBar *bar = [[[UINavigationBar alloc] init] autorelease];
对应的Java版
UINavigationBar bar = UINavigationBar.alloc().init().autorelease();//Java没有指针,因此星号去掉了
Objective-C的类分为接口定义和实现两个部分。接口定义(Interface)放在头文件中,文件扩展名是.h,实现(implementation)放在实现文件中,文件扩展名是.m(也有.mm的扩展名,表示Objective-C和C++混编的代码)。
接口定义也能够写在.m文件中,但最好不要这么干
须要注意的是,与Objective-C的interface概念最接近的是C和C++里的头文件,它与implementation是成双成对出现的,做用是声明类的成员变量和方法。它与Java的interface概念彻底不一样:
在Objective-C里,和Java的Interface概念类似的是Protocol,下文会讲到。
请看示例:
Interface
@interface MyClass { int memberVar1; id memberVar2; } -(return_type) instance_method1; -(return_type) instance_method2: (int) p1; -(return_type) instance_method3: (int) p1 andPar: (int) p2; @end
Implementation
@implementation MyClass { int memberVar3; } -(return_type) instance_method1 { .... } -(return_type) instance_method2: (int) p1 { .... } -(return_type) instance_method3: (int) p1 andPar: (int) p2 { .... } @end
接口和实现以@interface、@implementation开头,都以@end结束。“@”符号在Objective-C中是个很神奇的符号。
冒号也是方法名的一部分,method和method:是两个不一样的方法名,不是overload,第二个带参数。
上述代码对应的Java版:
public class MyClass { protected int memberVar1; protected pointer memberVar2; private int memberVar3; public (return_type) instance_method1() { .... } public (return_type) instance_method2(int p1) { .... } public (return_type) instance_method3andPar(int p1, int p2) { .... } }
写在.h头文件里的方法都是公开的,Objective-C里没有私有方法的概念(没有你说个蛋啊,哈哈哈哈)。
官方并无提到Objective-C怎么实现私有方法,我查阅了stackoverflow,统一的答案是,要实现私有方法的效果只能借助Category,不过,根据个人测试,即便采用了Category,也不能阻止外部的代码调用这个“私有方法”,只是Xcode不支持“私有方法”的自动完成,并会有警告提示,运行的时候,仍是会成功的。各位看官知道有这么回事就能够了,这里不深讲。
类方法就是Java、PHP里的Static Method,不用实例化就能调。类方法有一个加号前缀。 示例:
类定义
@interface MyClass +(void) sayHello; @end @implementation MyClass +(void) sayHello { NSLog(@"Hello, World"); } @end
使用
[MyClass sayHello];
实例方法就是Java、PHP里的普通方法,必须实例化才能调。实例方法有一个减号前缀。 示例:
类定义
@interface MyClass : NSObject -(void) sayHello; @end @implementation MyClass -(void) sayHello { NSLog(@"Hello, World"); } @end
使用
mycls = [MyClass new]; [mycls sayHello];
selector就是一个方法指针,相似PHP里的动态方法名:
<?php class Hello { public function sayHello() {} public function test() { $fun_name = "sayHello"; $this->$fun_name(); } }
在Objective-C里,selector主要用来作两类事情:
@implementation DemoViewController - (void)downButtonPressed:(id)sender {//响应“按钮被按下事件”的方法 UIButton *button = (UIButton*)sender; [button setSelected:YES]; } - (void)drawAnButton { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = _frame; btn.tag = 1; btn.backgroundColor = [UIColor clearColor]; [btn addTarget: self action: @selector(downButtonPressed:) forControlEvents: UIControlEventTouchUpInside];//当这个按钮被按下时,触发downButtonPressed:方法 } @end
@implementation ETHotDealViewController - (void)viewDidLoad { //获取数据源 HotDealDataSource *ds = [[HotDealDataSource alloc]init]; [ds reload]; _items = ds.items; [self performSelector: @selector(refreshTable) withObject: self afterDelay: 0.5];//延迟0.5秒调用refreshTable方法 } -(void)refreshTable { [self.tableView reloadData]; } @end
这个例子中,获取数据源是经过ASIHTTP组件异步调用服务端HTTP接口,refreshTable要用到数据源返回回来的数据,若是不延迟0.5秒,就会马上执行,执行的时候数据还在路上呢,页面就要变空白了。
继承是写在Interface定义里面的。语法为:子类名在左,父类名在右,中间用冒号分隔。 示例:
@interface MyClass : NSObject @end
对应的Java版本是:
public class MyClass extends NSObject { }
就是Java、PHP里的Interface。
协议的定义用@protocol关键字:
@protocol Printable -(void)print:(NSString)str; @end
对应的Java版本是:
publilc interface Printable { public void print(String str); }
协议自己也能够继承别的协议:
@protocol Printable <NSObject> -(void)print:(NSString)str; @end
对应的Java版本:
public interface Printable extends NSObject { public void print (String str); }
协议能够包含可选方法,顾名思义,可选方法能够不被类实现:
@protocol Printable @optional -(void)print:(NSString)str; @end
加了@optional关键字,一个类在implements这个协议时,即可以不实现print:方法。
Java里没有相似的实现,除了Collection里会有一些方法带有optional的注释,但Collection是个特例。
一个类实现某些协议是写在Interface定义里面的。语法为:协议名用尖括号包裹,多个协议名用逗号隔开,协议写在父类的右边(若是没有父类就直接写在子类右边)。
示例:
@interface class MyClass : NSObject <Printable, Drawable> @end
Printable, Drawablw就是两个协议。
对应的Java版本是:
public class MyClass extends NSObject implements Printable, Drawable { }
分类能够给一个已经存在的类增长方法,而不用去改它的源码。Java和PHP中都没有相似的特性。
好比说,NSObject是一个Objective-C内置的系统类,咱们想给它增长toJson方法,就像这样:
头文件:NSObject+Json.h
@interface NSObject (Json) -(NSString)toJson; @end
实现文件:NSObject+Json.m
@implementation NSObject (Json) -(NSString)toJson { //... } @end
使用的时候,只要包含NSObject+Json.h,实例化NSObject类,就可使用toJson方法了:
import "NSObject+Json.h" @implatementation XYZController -(void)test { NSObject *obj = [[NSObject alloc]init]; NSString *str = [obj toJson]; } @end
固然了,NSObject原本的那些方法依然仍是能够用的,什么都没变,只是多了个toJson方法。看起来是否是和继承没太多差异呢(除了使用的时候实例化的是NSObject,而不是JsonObject)?再看一个继承实现不了的例子:
头文件:NSObject+Json+XML.h
@interface NSObject (Json) -(NSString)toJson; @end @interface NSObject (XML) -(NSString)toXML; @end
实现文件:NSObject+Json+XML.m
@implementation NSObject (Json) -(NSString)toJson { //... } @end @implementation NSObject (XML) -(NSString)toXML { //... } @end
使用:
import "NSObject+Json+XML.h" @implatementation XYZController -(void)test { NSObject *obj = [[NSObject alloc]init]; NSString *json = [obj toJson]; NSString *xml = [obj toXML]; } @end
Cocoa是Mac OS App的开发框架,Cocoa Touch是iOS开发用的框架,Cocoa Touch和Cocoa大部分是同样的,只是Cocoa Touch多了一些移动设备特有的东西,如:触摸屏、加速度传感器、GPS定位。Cocoa中多任务、多窗口的特性,在Cocoa Touch中也是没有的(或者跟Cocoa不彻底同样的)。
就像学了Java语言还要再学一些Spring、Hibernate、Struts(或者其它相似的Java类库)才能开始作J2EE应用同样,学过Objective-C语言以后,也要再学习Cocoa Touch框架才能顺利地开发iOS应用。
Cocoa Touch大量使用Delegate(委派)设计模式。
快捷键:Comman R
推荐在Finder中新建好的再添加进来
在Xcode中打开你的项目,在Xcode顶部工具栏的Stop按钮(Run按钮右边那个黑色正方形按钮)右边,有个下拉菜单,显示着 “ToolBarSearch > iPhone 5.0 Simulator” (即 你的应用英文名 > 当前选中的调试 ),点击这个下拉菜单,选中iPhone 5.0 Simulator(这里的5.0是指iOS版本,不是iPhone5的意思,若是你的项目是iPad应用,请选iPad 5.0 Simulator),再按“Run”按钮,Xcode就会自动把当前正在编辑开发的应用编译并安装到模拟器上。
在模拟器上操做时,若是执行过程当中遇到了你在Xcode里设置的断点,模拟器会暂停运行,并将当前活动窗口切换回Xcode,供你调试。
在Xcode里增长或者取消了断点,不须要从新编译和安装应用便可生效。
模拟器的“硬件”菜单,能够选择想要模拟什么设备,有iPad、iPhone可选。
在模拟器的“版本”菜单,能够选择要模拟什么版本的iOS。设备和版本是彼此独立的,iPhone 4S能够有5.0,5.1,6.1几种iOS版本,固然了,iPhone 5不可能有4.3的iOS版本。
用鼠标点击(不区分左右键)模拟器上的iPhone、iPad屏幕,就是在模拟用手指触摸iPhone,iPad的屏幕,能够实现一些触摸效果好比:
多指手势比较复杂,在白苹果笔记本上能够模拟简单的双指手势,白苹果的触控板自然支持多指触摸,但要定位到模拟器的区域再响应多指手势就须要借助一些额外的键啦:
手机上特有的输入法(好比九宫格输入法)不能模拟。模拟器默认的iOS软键盘只有英文输入,在测试应用的时候,咱们要用到中文,有两个办法:
若是要输入大量文本,使用模拟器里的软键盘效率过低,这时候可使用物理键盘,方法是:在Mac OS顶部的模拟器菜单栏,点击”硬件”菜单,勾选下拉菜单中的“模拟硬件键盘”。之后再用模拟器运行iOS应用时,点击iOS应用中的输入框,软键盘就不弹出来了,可直接使用Mac电脑的物理键盘输入。
注意:
但Mac电脑没有定位用的硬件(GPS)和软件基础,所以模拟器不能自动得到当前的地理位置,不能用模拟器测试定位功能。(注意,虽然WiFi也能够独立定位——iPad WiFi版没有GPS也能够定位,但Mac电脑的WiFi不具有定位相关的软件)
要在模拟器里测试依赖地理位置的功能(如”我附近的xx”),能够手工指定一个经纬度给模拟器,方法:在Mac电脑顶部的模拟器菜单,点击”调试 - 位置 - 自定位置”,会弹出一个对话框,在弹出的框内填入经纬度便可。
如何得到经纬度? 上谷歌地图(ditu.google.cn),在地图上找到你想要的位置(好比你想知道杭州大厦的位置,就在经过搜索框找到杭州大厦),点击右键,选择“这儿是什么”,搜索框中就会出现这个位置的经纬度了,前面是纬度,后面是经度。我们天朝的版图,都是北纬和东经。
Mac电脑有摄像头,但Mac OS没有设计API给iOS模拟器调用,因此,不能用模拟器测试对焦闪光灯等功能。
要在模拟器上测试依赖照片的功能,能够在代码里作一个workaround,即当代码检测到摄像头不可用时,弹出一个照片选择器,让测试人员从相册里选择一幅照片,来进行后续的操做(如照片美化、人脸识别、条码扫描)。
模拟器能验证你开发的iOS应用的大部分功能,但有些Mac设备上不具有的硬件,模拟器是不能模拟的。前文提到了一个绕过这些限制的办法,但获取当前位置、拍照、加速度感应这些是模拟不了的,一款应用发布给消费者以前,必需要在真实设备上验证过。
将未提交App Store审核经过的应用安装到iOS设备上测试,有三种办法:
破解Xcode是违法行为(越狱是合法的),并且挑版本挑得厉害,不是全部Xcode版本都能破解,也不是全部Xcode的破解版都能和越狱的iOS配合好。越狱+SSH上传跟企业部署同样效率低(部署效率低,没法激活Xcode中的断点),只能用于QA验收,不适合开发自测。综上所述,最适合开发实时测试的就是第一个正规途径了。下面重点讲这个:
苹果的Developer Program分为我的开发者和公司开发者,分别是每一年99美圆和每一年299美圆,分别能够注册100台和500台苹果测试设备。这个台数限制在一个付费年度内不会清空,好比说,2013年4月1日付费成功的,付费会员资格在2014年3月31日以前有效,这期间,注册一台就少一个名额,哪怕这个设备注册进来用了以后一分钟立刻又删掉了,减小的这个名额也不会回来。
在交钱以前,最好问一下,周围的同事,有没有已经交了钱的。若是有,你只须要注册一个免费的Apple ID(就是你在App Store安装软件用的Apple ID),请他发个邀请邮件给你,把你的Apple ID加入他的团队就能够了,苹果会认为大家两我的是一个团队的,大家分别用本身的帐号,共享100台设备的限额,这是合法的。
不想看下面各类点击各类页面跳转的直接用浏览器访问证书管理,你要登陆你就用Apple ID登陆(前提是交过钱,或者找交了钱的人把你加入团队了)。
不嫌烦,或者想知道下次没我这个文档的时候怎么进证书管理吗?按这个步骤操做:
页面上有一个“Your Certificate”区域,下方有个Download圆角按钮,这是你的我的证书,下载下来。再下面一行,有一句“If you do not have the WWDR intermediate certificate installed, click here to download now”,这个是苹果的公共证书,也下下来。
双击下载回来的证书,装证书时,会提示你输入密码,这是【钥匙串访问工具】在问你要你的Mac OS帐号开机密码(至关于linux里面的sudo),不是Apple ID的密码,不要搞错了。
若是你是和其它同事公用的帐号,让他给你一个私钥便可,就是一个扩展名为p12的文件,双击之,钥匙串访问会自动出来,须要你输入一个密码,这个密码问给你p12文件的人要,不是你的Mac OS系统开机密码,也不是你的Apple ID密码。
回到Xcode主界面,在Stop按钮(Run按钮右边那个黑色正方形按钮)右边,有个下拉菜单,显示着 “ToolBarSearch > iPhone 5.0 Simulator” (即 你的应用英文名 > 当前选中的调试 ),点击这个下拉菜单,选中你的真机设备名,再按“Run”按钮,Xcode就会自动把当前正在编辑开发的应用编译并安装到真机上测试啦!
IPA包本质上是一个ZIP压缩包,只不过它有着特殊的目录结构,扩展名是ipa,制做方法以下:
除App Store外,还有许多其它的iOS应用市场(如91助手,同步推等等),若是一个应用须要发布到不少个应用市场,且他们的代码略有不一样(好比说,统计代码不一样),按上述方法手工修改源码再打包,再还原,比较容易出错。好消息是,Xcode是有命令行的,咱们能够写一个shell脚本,先用se自动修改源码,再调用Xcode的命令行来编译以获得your——app.app目录,最后调用zip、mv等命令把上一个章节讲的ipa打包动做自动执行。
iOS App里的控件尺寸和字体大小都是指Point,Retina设备(iPhone 4,4S,5;the new Pad)和非Retina设备(iPhone 3GS,iPad,iPad 2)的Point数是同样的,尽管iPhone 4的分辨率是3GS的2倍。好比说,10point在Retina设备里是20 pixel,在非Retina设备(iPhone 3G)上则是10 pixel。
项目成员间交流时,应使用Point,不要使用pixel。
iOS应用中常常出现xxxx@2x.png这样的文件名,它们是给retina设备用的高分辨率大图,用svn命令行操做它们的时候会被@符号干扰,解决方案是在svn命令末尾加上一个@符号,如:
svn del icon@2x.png@ svn info Default@2x.png@
若是一次移动了几十个png文件再svn commit的,能够用shell批处理:
svn status | awk '($1=="!"){print $2}' | grep -v @ | xargs svn del
上面这个命令是将文件名不包含@符号的,且已经不在硬盘上的文件从svn version controll中删掉
for file in `svn status | awk '($1=="!"){print $2}' `; do svn del $file"@"; done
上面这个命令是将文件名包含@符号的,且已经不在硬盘上的文件从svn version controll中删掉
svn add同上, 如法炮制便可.
推荐在Finder里建好目录再到Xcode的Project Navigator中点击“Add Files to”添加到项目中
iPhone 5与以前的iPhone不同,采用了4寸Retina屏,因此它的Point数变成了320 * 568 points