看了眼 tinyfool 经常提的日历控件

2016-11-27 18:49:43 +08:00
 EagleB

先贴上源码地址:Here 代码是是 08 年写的,这点还是非常服的,这个时候我还在上高中。 08 年到现在 OC 在一些特性上改进很多,其中使用的CFGregorianDate相关 api 在 iOS 8.0 之后也不建议使用了,所以这里我只说我确认不是好的实践的部分。

先来看下头文件:

//
//  CalendarView.h
//  ZhangBen
//
//  Created by tinyfool on 08-10-26.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol CalendarViewDelegate;

@interface TdCalendarView : UIView {
	CFGregorianDate currentMonthDate;
	CFGregorianDate currentSelectDate;
	CFAbsoluteTime	currentTime;
	UIImageView* viewImageView;
	id<CalendarViewDelegate> calendarViewDelegate;
	int *monthFlagArray; 
}

@property CFGregorianDate currentMonthDate;
@property CFGregorianDate currentSelectDate;
@property CFAbsoluteTime  currentTime;

@property (nonatomic, retain) UIImageView* viewImageView;
@property (nonatomic, assign) id<CalendarViewDelegate> calendarViewDelegate;
-(int)getDayCountOfaMonth:(CFGregorianDate)date;
-(int)getMonthWeekday:(CFGregorianDate)date;
-(int)getDayFlag:(int)day;
-(void)setDayFlag:(int)day flag:(int)flag;
-(void)clearAllDayFlag;
@end



@protocol CalendarViewDelegate<NSObject>
@optional
- (void) selectDateChanged:(CFGregorianDate) selectDate;
- (void) monthChanged:(CFGregorianDate) currentMonth viewLeftTop:(CGPoint)viewLeftTop height:(float)height;
- (void) beforeMonthChange:(TdCalendarView*) calendarView willto:(CFGregorianDate) currentMonth;
@end

代码格式我就不说了,空格写的很随意,大小写对于我这种强迫症来说也很受不了。最重要的是我认为稍微参考下苹果 framework 中函数的命名方式,就不会写出协议中这么扯淡的命名。 interface 中的命名大多数都还不错,但是-(void)setDayFlag:(int)day flag:(int)flag;这个是什么鬼,我认为- (void)setFlag:(int)flag forDay:(int)day;更好。

下面来看下源文件:

源文件中定义了全局的几个变量:

const float headHeight=60;
const float itemHeight=35;
const float prevNextButtonSize=20;
const float prevNextButtonSpaceWidth=15;
const float prevNextButtonSpaceHeight=12;
const float titleFontSize=30;
const int	weekFontSize=12;

这几个变量主要是来控制试图的大小、字体的大小,只有在这个文件内部试哟哦难过,没有用static修饰,不是很明白,可能 tinyfool 记忆里好,不会再工程中其他地方使用相同名字的变量。

学 C 语言的时候,大概都做过这么一个练习:获取某年某月的天数。来看看 tinyfool 的实现:**

-(int)getDayCountOfaMonth:(CFGregorianDate)date{
	switch (date.month) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			return 31;
			
		case 2:
			if((date.year % 4==0 && date.year % 100!=0) || date.year % 400==0)
				return 29;
			else
				return 28;
		case 4:
		case 6:
		case 9:		
		case 11:
			return 30;
		default:
			return 31;
	}
}

interesting ,自行体会一下。

实现中有很多类似的实践(个人认为这不是好的实践):

- (void)movePrevMonth{
	if(currentMonthDate.month>1)
		currentMonthDate.month-=1;
	else
	{
		currentMonthDate.month=12;
		currentMonthDate.year-=1;
	}
	[self movePrevNext:0];
}

再来看下这个类的析构函数:

- (void)dealloc {
    [super dealloc];
    free(monthFlagArray);
}

Excuse me. 这里虽然不太可能出现崩溃的情况,但不是应该先释放子类持有的资源?

最后,总结一些 tinyfool 的变量命名风格:title_MonthweekfonttabHeights_width


我观察到的是,如果有人在微博上反驳他什么,他通常的回应是毫无道理(有道理的时候也有,少),其他的不想评价,怕被喷。

8565 次点击
所在节点    程序员
63 条回复
fukual66
2016-11-28 16:51:50 +08:00
莫名想起了当年激动人心的演讲,我在现场,听得我瑟瑟发抖,找回当时评价的链接[地址]( https://www.zhihu.com/question/44019457)
zengcool
2016-11-28 20:11:37 +08:00
我一直以为,敢于开源自己项目的人都是勇士。觉得 tinyfool 解释的那么清楚,算是非常认真负责了。我想想自己写过的代码,哎呀,让我死了算了。哈哈~
sopato
2016-11-28 20:56:42 +08:00
翻出多年前的代码来找刺,确实有点过分了哈~~~~~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/323650

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX