初中的时光是一段艰辛,但幸福的时光,在这一段时光中同样我遇到了我人生中第二个贵人。记得在小学毕业的那个暑假里,我知道上了初中会开一门叫做英语的课程,那时候在我们那里有好多上过初中、高中的在我们小学开英语补习班,也许是因为家庭条件的原因,我没有去。在家里我拿着我哥以前用过的英语书,支支吾吾的一个暑假学会了A,B,C,D,E,F,G,......这首儿歌。步入初中校园,给我的第一个感觉是很大,而且有一座4层高的教学楼,我被排到了一、四班,班主任是一个教语文的男老师,我至今想起那位老师还有点恶心,具体为啥就不说了(此处略去),给我们教英语的是一个女老师,同学们给她起了一个外号"鸡大婶",不知道是因为每天让人像鸡一样跟着她读英语单词的原因还是本身长的有点像的原因。
英文我们现在都知道很重要,尤其是我们做IT这一行的,在我身边就有好多人就是因为这个而与大学失之交臂。当时刚上初中的我并不知道英语的重要性,但是我还是想学好这一门课(估计是看电视剧影响的),所以我就让父母花了100多元买了一个复读机,我很高兴,每天下完学回来就插上耳机,听英语。还是那句话“一个好的老师可以影响一群人的一生,一个烂老师可以毁掉祖国的未来”,我在这里并不是什么诋毁或者胡说,有的人可能会说“自己不努力,关老师什么是,同一个班别人能考100,你为啥只考60分,说明是你不够用功”,当时有好多人这样激励自己的孩子或自己的学生,我听了不下100遍了,我一想,是啊,这句话很有道理。不过现在我是完全的不认同,我认为就是因为这句话而毁掉了很多幼小的学生,使他们的潜力没有被开发出来,而最终流为城市边缘人或者农民工。我认为一个合格的老师应该知道怎么去让学生对这一门课产生兴趣,然后才是学习方法,最后才是课本内容。学生不是农民工,老师也不是包工头,说学生不努力的老师我真不知道他(她)当老师良心上能过得去。我像很多农村里的娃一样,不是什么特例,也会遇到这种老师,我的初中英语老师可以说就是一个典型。没有兴趣也全都不是老师的错,也许是因为我天资太过愚钝,所以我的英语和我的复读机从此江河日下。。。。。。再也没有起来过。
到了初二,我们那一届开始开一门课叫做物理。给我们带这门课的老师是一个男老师,这就是我生命中第二个贵人。在这里就给大家讲讲我的物理学习经历吧:刚开始接触物理是在初二第一学期,这一学期我对这门课没有一点感觉,作业不会做(抄别人的),听课也没印象,就这样过了一学期。到了第二学期,学校分班了,我被分到了二、8班,班主任就是我们的物理老师(和上面提到的男老师是同一个人),我有一天中午和同学在学校附近的转,那边开了一个小书屋,里面有各种初中的辅导书,看这里面的各种新书,很想买一本,以前在小学的时候从来没有买过参考书,那时候很渴望能有新书,但是家庭条件不允许。后来我就每天少吃一点省了两周,终于可以买起那本我现在还记忆犹新的书《一本全》,这是一本像练习册一样的物理参考书。也许是因为班主任是物理老师,所以我当时很想学好物理,同时我在做《一本全》的时候发现很有趣,我下课休息时间有时候也要拿出来做两道题,就这样又是在期中考试中物理考了全班第一,从那以后,我也成了物理课代表(就是给老师端物理作业本的),从此我就与物理结下了不解之缘。后来,我常常会在上课的时候指出老师讲错的地方,从哪以后感觉物理很简单,没有题可以难道我,我的年级排名也从100多名,排到了20多名(很多分数都是英语影响的)。
很快就到了人生的第一个路口“中考”,中考当时对我来说我没有感到丝毫的压力,因为我是付出艰辛,备战了一年的。当时我们的初中是在我们镇上,我没有在学校住宿,6里的路每天是早上走过去然后晚上走回来。记得当时每天早上5点多就要起床,然后稍微吃一点(我早上不爱吃饭)就去学校了,冬天的时候早上天还是黑的,我和同村的3、4个人就得去学校,每次我们到学校后离学校近的街道边住的同学还都没有来。现在想起当时的情形,还时不时的自我鼓励继续努力。上了初三,哥哥去深圳了,家里的很多农活,我也渐渐的承担了起来,所以心理比较成熟了,明白自己的家庭比较困难,需要努力学习去改善。从那个时候我突然喜欢看名人的传记和励志故事之类的书了,我在隔壁存放粮食的屋子里面给自己支了一个桌子,在桌子前面的墙壁上贴了不少名人头像和励志名言,每天晚上放学回来都会很自觉的学到11点。从哪个时候开始我变了。。。。学习不再是一种任务,而是一个改变家庭命运的出路。
首先说一下 这是我自己的个人笔记,如果想看看,不用看细节,可以看流程。
定义一个线程池 ExecutorService pool = Executors.newFixedThreadPool(15);
运用线程获取网络数据 即编辑相关的访问方法以及参数
public static String sendDataByHttpClientPost(String url, List<NameValuePair> parameters) throws Exception { HttpClient client = new DefaultHttpClient(); client.getParams().setParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, TIME_OUT); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, TIME_OUT); HttpPost httppost = new HttpPost(url); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8"); httppost.setEntity(entity); HttpResponse ressponse = client.execute(httppost); int code = ressponse.getStatusLine().getStatusCode(); if (code == Status.SUCCESS) { InputStream is = ressponse.getEntity().getContent(); byte[] result = getBytes(is); return new String(result); } else { throw new IllegalStateException("服务器状态异常"); } }
获得相关JSON数据进行解析,当然首先得创建一个实体类 即下面方法的参数 clazz,参数jsonStr就是获得的网络JSON数据,clazz这个就是一个数组对象了,所包含的字段,可以在实体类中定义相关的变量。
STATUS STATUS_SUCCESS INFO 这些是我自己写的相关常量
public static <T> List<T> parseList(String jsonStr, Class<T> clazz) throws JSONException { JSONObject json = new JSONObject(jsonStr); String response = json.getString(STATUS); List<T> list = new ArrayList<T>(); if (response != null && response.equals(STATUS_SUCCESS)) { String info = json.getString(INFO); if (!TextUtils.isEmpty(info) && !info.equals("null")) { list = (List<T>) JSON.parseArray(info, clazz); return list; } else { return list; } } else { throw new IllegalStateException(); } }
上面方法得到的就是一个我们要在ListView当中显示的数组数据。然后将它通过消息Message发送到主线程的Handler中进行处理 即
message = handler.obtainMessage(Status.SUCCESS, list); message.sendToTarget();
SUCCESS 为自己写的常量
这样就拿到了数组了,现在的问题是,怎样实时显示到ListView当中, 步骤可以这样:
一 先定义一个类 它进行了适配器当中数据的更改、刷新 即
package com.sinosoft.foodsafemanagerv2.function.task.unionmeeting; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.content.Context; import android.widget.ListView; import com.sinosoft.adpter.MySimpleAdpter; import com.sinosoft.foodsafemanagerv2.R; import com.sinosoft.foodsafemanagerv2.entity.Case; public class UnionRecordListView { private ListView listView; private MySimpleAdpter myAdapter; private ArrayList<HashMap<String, Object>> datas; private Context context; private String[] from; public UnionRecordListView() { super(); } public UnionRecordListView(final Context context, ListView listView) { this.context = context; this.listView = listView; from = new String[] { "img", "type_name", "time_type" }; datas = new ArrayList<HashMap<String, Object>>(); myAdapter = new MySimpleAdpter(context, datas, R.layout.layout_recordlistview_item, from, new int[] { R.id.imageview, R.id.name_or_type_text, R.id.type_or_time_text }); listView.setAdapter(myAdapter); } /** * 设置数据 * * @param list */ public void setDatas(List<Case> list) { ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>(); for (Case c : list) { HashMap<String, Object> map = new HashMap<String, Object>(); String imgs = c.getImgIds(); map.put(from[0], c.getCaseId()); map.put(from[1], c.getUnitName()); map.put(from[2], c.getTypeName()); data.add(map); } this.datas = data; myAdapter.setListData(data); myAdapter.notifyDataSetChanged(); } }
苹果开发编码规范
参考资料:
• Apple: Coding Guidelines for Cocoa
• Google:
Objective-C Style Guide
• Three20:
Source code style guildelines
正文:
• 格式化代码
◦ 指针“*”号的位置
▪ 如:NSString *varName;
◦ 空格
VS tabs
▪ 只允许使用空格,将编辑器设置为1个TAB
= 2个字符缩进
◦ 每行的长度
-
▪ 每行最多不得超过100个字符
-
▪ 以15寸Macbook Pro的大小,每行100个字符时能最大化地同时容下编辑器和iPhone模拟器
-
▪ Google的80字符的标准有点少,这导致过于频繁的换行(Objectve-C的代码一般都很长)
-
▪ 通过 “Xcode => Preferences => TextEditing => 勾选Show Page Guide / 输入
100 => OK” 来设置提醒◦ 方法的声明和定义
-
▪ 在 - OR + 和返回值之间留1个空格,方法名和第一个参数间不留空格。如:- (void)doSomethingWithString:(NSString *)theString {
...}
-
▪ 当参数过长时,每个参数占用一行,以冒号对齐。如:- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect interval:(float)theInterval {
...}
-
▪ 如果方法名比参数名短,每个参数占用一行,至少缩进4个字符,且为垂直对齐(而非使用冒号对齐)。如:
- (void)short:(GTMFoo *)theFoolongKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval { ...
}
◦ 方法的调用
-
▪ 调用方法沿用声明方法的习惯。例外:如果给定源文件已经遵从某种习惯,继续遵从那种习惯。
-
▪ 所有参数应在同一行中,或者每个参数占用一行且使用冒号对齐。如:
[myObject doFooWith:arg1 name:arg2 error:arg3];
或
[myObject doFooWith:arg1 name:arg2
error:arg3];
-
▪ 和方法的声明一样,如果无法使用冒号对齐时,每个参数一行、缩进4个字符、垂直对其(而非使用冒号对齐)。如:
[myObj short:arg1longKeyword:arg2
evenLongerKeyword:arg3];
◦ @public 和 @private
▪ @public 和 @private使用单独一行,且缩进1个字符
◦ Protocals
-
▪ 类型标示符、代理名称、尖括号间不留空格。
-
▪ 该规则同样适用于:类声明、实例变量和方法声明。如:
@interface MyProtocoledClass : NSObject<NSWindowDelegate> { @private
id<MyFancyDelegate> _delegate; }
- (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
@end
-
▪ 如果类声明中包含多个protocal,每个protocal占用一行,缩进2个字符。如:@interface CustomViewController : ViewController<
AbcDelegate,
DefDelegate>{
...}
•命名
◦ 类名
-
▪ 类名(及其category name 和 protocal name)的首字母大写,写使用首字母大写的形式分割单词
-
▪ 在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同的前缀影响可读性。
-
▪ 在面向多应用的代码中,推荐使用前缀。如:GTMSendMessage◦ Category Name
▪ 待完善◦ 方法名
-
▪ 方法名的首字母小写,且使用首字母大写的形式分割单词。方法的参数使用相同的规则。
-
▪ 方法名+参数应尽量读起来像一句话(如:)。在这里查看苹果对方法命名的规范。
-
▪ getter的方法名和变量名应相同。不允许使用“get”前缀。如:
- (id) getDelegate; // 禁止
- (id)delegate; // 对头
-
▪ 本规则仅针对Objective-C代码,C++代码使用C++的习惯
◦ 变量名
-
▪ 变量名应使用容易意会的应用全称,且首字母小写,且使用首字母大写的形式分割单词
-
▪ 成员变量使用“_”作为前缀(如:“NSString *_varName;”。虽然这与苹果的标准(使
用“_”作为后缀)相冲突,但基于以下原因,仍使用“_”作为前缀。
▪ 使用“_”作为前缀,更容易在有代码自动补全功能的IDE中区分“属性(self.userInfo)”和“成员变量(_userInfo)”
-
▪ 常量(#define, enums, const等)使用小写“k”作为前缀,首字母大写来分割单词。如:
kInvalidHandle
•注释
◦ 待完善• Cocoa 和 Objective-C特有的规则
-
成员变量使用@private。如:
@interface MyClass : NSObject { @private
id _myInstanceVariable; }
// public accessors, setter takes ownership - (id)myInstanceVariable; - (void)setMyInstanceVariable:(id)theVar; @end
-
Indentify Designated Initializer▪ 待完善
-
Override Desingated Initializer
▪ 待完善◦ 初始化
▪ 在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的
▪ 内存中所有的新创建的对象(isa除外)都是0,所以不需要重复初始化为“0”或“nil”◦ 避免显式的调用+new方法
▪ 禁止直接调用NSObject的类方法+new,也不要在子类中重载它。使用alloc和init方法◦ 保持公共API的简洁性
▪
待完善
◦ #import VS #include
▪ 使用#import引入Ojbective-C和Ojbective-C++头文件,使用#include引入C和C++头文件
◦ import根框架(root
frameworks),而非各单个文件
▪ 虽然有时我们仅需要框架(如Cocoa
或 Foundation)的某几个头文件,但引入根文件编译
器会运行的更快。因为根框架(root frameworks)一般会预编译,所以加载会更快。再次强调:使用
#import 而非
#include
来引入Objective-C框架。如:
#import <Foundation/NSArray.h> //
禁止
#import <Foundation/NSString.h>
...
#import <Foundation/Foundation.h> // 对头◦ 创建对象时尽量使用autorelease
-
▪ 创建临时对象时,尽量同时在同一行中 autorelease 掉,而非使用单独的 release 语句
-
▪ 虽然这样会稍微有点慢,但这样可以阻止因为提前 return 或其他意外情况导致的内存泄露。
通盘来看这是值得的。如:
// 避免这样使用(除非有性能的考虑)
MyController* controller = [[MyController alloc] init];
// ... 这里的代码可能会提前return ...
[controller release];
// 这样更好
MyController* controller = [[[MyController alloc] init] autorelease];◦ 先autorelease,再retain
-
▪ 在为对象赋值时,遵从“先autorelease,再retain”
-
▪ 在将一个新创建的对象赋给变量时,要先将旧对象release掉,否则会内存泄露。市面上有很
多方法来handle这种情况,这里选择“先autorelease,再retain”的方法,这种方法不易引入error。注意:在循环中这种方法会“填满”autorelease pool,稍稍影响效率,但是Google和我( :P )认为这个代价是可以接受的。如:
- (void)setFoo:(GMFoo *)aFoo {[foo_ autorelease]; // 如果foo_和aFoo是同一个对象(foo_ == aFoo),dealloc不会被调用
foo_ = [aFoo retain]; }
◦ dealloc的顺序要与变量声明的顺序相同
▪ 这有利于review代码
▪ 如果dealloc中调用其他方法来release变量,将被release的变量以注释的形式标注清楚◦ NSString的属性的setter使用“copy”
▪ 禁止使用retain,以防止意外的修改了NSString变量的值。如:
- (void)setFoo:(NSString *)aFoo { [foo_ autorelease]; foo_ = [aFoo copy];
}
或
@property (nonatomic, copy) NSString *aString;
◦ 避免抛出异常(Throwing Exceptions)▪ 待完善
◦ 对
nil
的检查
▪ 仅在有业务逻辑需求时检查nil,而非为了防止崩溃
▪ 向 nil 发送消息不会导致系统崩溃,Objective-C运行时负责处理。◦ BOOL陷阱
-
▪ 将int值转换为BOOL时应特别小心。避免直接和YES比较
-
▪ Objective-C中,BOOL被定义为unsigned char,这意味着除了 YES(1) 和NO(0)外它
还可以是其他值。禁止将int直接转换(cast or convert)为BOOL。
-
▪ 常见的错误包括:将数组的大小、指针值或位运算符的结果转换(cast or convert)为
BOOL,因为该BOOL值的结果取决于整型值的最后一位
-
▪ 将整型值转换为BOOL的方法:使用三元运算符返回YES / NO,或使用位运算符(&&,||,!)
-
▪ BOOL、_Bool和bool之间的转换是安全的,但是BOOL和Boolean间的转换不是安全的,所以
将Boolean看成整型值。
-
▪ 在Objective-C中,只允许使用BOOL
-
▪ 如:
// 禁止
- (BOOL)isBold {return [self fontTraits] & NSFontBoldTrait; }
- (BOOL)isValid { return [self stringValue];
}
// 对头
- (BOOL)isBold {return ([self fontTraits] & NSFontBoldTrait) ? YES : NO; }
- (BOOL)isValid { return [self stringValue] != nil;
} - (BOOL)isEnabled {
return [self isValid] && [self isBold]; }
-
▪ 禁止直接将BOOL和YES/NO比较,如:// 禁止
BOOL great = [foo isGreat]; if (great == YES)
...
// 对头
BOOL great = [foo isGreat];if (great)...
◦ 属性
▪ 命名:与去掉“_”前缀的成员变量相同,使用@synthesize将二者联系起来。如:
// abcd.h @interface MyClass : NSObject {
@private NSString *_name;
} @property (copy, nonatomic) NSString *name; @end
// abcd.m @implementation MyClass @synthesize name = _name; @end
▪ 位置:属性的声明紧随成员变量块之后,中间空一行,无缩进。如上例所示▪
严把权限:对不需要外部修改的属性使用readonly
▪
NSString使用copy而非retain
▪
CFType使用@dynamic,
禁止使用@synthesize
▪ 除非必须,使用nonatomic• Cocoa Pattern
◦ Delegate Pattern(委托)
-
▪ delegate对象使用assign,禁止使用retain。因为retain会导致循环索引导致内存泄露,
并且此类型的内存泄露无法被Instrument发现,极难调试
-
▪ 成员变量命名为_delegate,属性名为delegate
◦ Model/View/Controller▪ Model和View分离
▪ 不多解释
▪ Controller独立于View和Controller▪ 不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性很差
▪ Controller负责业务逻辑代码,且Controller的代码与view尽量无关
▪ 使用@protocal 定义回调APIs,如果并非所有方法都是必须的,使用@optional标示•其他
◦ init方法和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置◦ 使用空格将相同的变量、属性对齐,使用换行分组