iOS学习笔记总结一(持续更新)
2014-04-09 16:28
561 查看
1、在ARC项目中使用非ARC框架或者类库的解决方案
只需在TARGETS里的Build Phases中,找到 Compile Sources,把涉及到非ARC的类后面加上 -fno-objc-arc标志(添加:-fobjc-arc,就可以让旧项目支持arc)。如果使用了arc,在@property声明中,用strong和weak代替相应的retain,copy,和assign.如下图:
2、retain和copy的区别
copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
那上面的是什么意思呢?
Copy其实是建立了一个相同的对象,而retain不是:
比如一个NSString对象,地址为0×1111,内容为@”STR”
Copy到另外一个NSString之 后,地址为0×2222,内容相同,新的对象retain为1, 旧有对象没有变化
retain到另外一个NSString之 后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
也就是说,retain是指针拷贝,copy是内容拷贝。
3、什么时候用assign、什么时候用retain和copy呢
推荐做法是NSString用copy,delegate用assign(且一定要用assign,不要问为什么,只管去用就是了,以后你会明白的),非objc数据类型,比如int,float等基本数据类型用assign(默认就是assign),
而其它objc类型,比如NSArray,NSDate用retain。
4、对于不同的viewcontroller之间数据的共享和处理
1)采用代理模式子viewcontroller设计代理协议,定义协议接口,父viewcontroller 实现协议接口,实现子viewcontroller 退出时将相关数据更新到父视图。
2)采用ios的消息机制
父viewcontroller注册消息 子viewcontroller 发送消息,触发父viewcontroller的消息处理。
3)采用database做为数据中间的存储媒介,子viewcontroller将状态数据存入DB,父viewcontroller从DB获取数据更新view。
4)采用ios的NSDefault
存储
5)通过AppDelegate 中定义全局变量实现中间数据的存储。
5、代码混编
1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题
3)在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。
如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。
如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。
总结:只要cpp文件和cpp
include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。而obj-c混用cpp就简单了,直接用就可以,因为obj-c的编译器支持啊
6、代码中字符串换行
NSString *string =@"ABCDEFGHIJKL" \ "MNOPQRSTUVsWXYZ";
7、判断一个字符串是否包含另一个字符串
[str1 rangeOfString:str2].length != 0 ? @"包含" : @"不包含"
8、没有用到类的成员变量的,都写成类方法
9、让程序退出后台时继续运行10分钟
在XXAppDelegate中增加:UIBackgroundTaskIdentifier bgTask;- (void)applicationDidEnterBackground:(UIApplication *)application { bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ // 10分钟后执行这里,应该进行一些清理工作,如断开和服务器的连接等 // ... // stopped or ending the task outright. [application endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; if (bgTask == UIBackgroundTaskInvalid) { NSLog(@"failed to start background task!"); } // Start the long-running task and return immediately. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Do the work associated with the task, preferably in chunks. NSTimeInterval timeRemain = 0; do{ [NSThread sleepForTimeInterval:5]; if (bgTask!= UIBackgroundTaskInvalid) { timeRemain = [application backgroundTimeRemaining]; NSLog(@"Time remaining: %f",timeRemain); } }while(bgTask!= UIBackgroundTaskInvalid && timeRemain > 0); // 如果改为timeRemain > 5*60,表示后台运行5分钟 // done! // 如果没到10分钟,也可以主动关闭后台任务,但这需要在主线程中执行,否则会出错 dispatch_async(dispatch_get_main_queue(), ^{ if (bgTask != UIBackgroundTaskInvalid) { // 和上面10分钟后执行的代码一样 // ... // if you don't call endBackgroundTask, the OS will exit your app. [application endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; } }); }); } - (void)applicationWillEnterForeground:(UIApplication *)application { // 如果没到10分钟又打开了app,结束后台任务 if (bgTask!=UIBackgroundTaskInvalid) { [application endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; } }后台时,如果某些代码你不希望执行,可以加以下条件:
UIApplication *application = [UIApplication sharedApplication]; if( application.applicationState == UIApplicationStateBackground) { return; }
有的app虽然我们不允许通知,但还是会弹出消息,应该是设置了定时器,到某一时间就让程序后台运行一会,从服务器更新数据,然后显示出来。
10、_cmd
在Apple的官方介绍里看到轻描淡写的说了一句:“The _cmd variable is a hidden argument passed to every method that is thecurrent selector”,其实说的就是_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样。
表示该方法的selector,可以赋值给SEL类型的变量,可以做为参数传递。
例如一个显示消息的方法:
-(void)ShowNotifyWithString:(NSString*)notifyString fromMethod:(SEL) originalMethod;
originalMethod就是调用这个方法的selector。 调用如下:
NSString *stmp = @"test"; [self ShowNotifyWithString:stmp fromMethod:_cmd];比如,我们要打印当前要调用的方法,可以这样来写:
- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"Current method: %@ %@",[self class],NSStringFromSelector(_cmd)); }
输出结果如下:TestingProject[570:11303] Current method: FirstViewController viewDidLoad
11、一个不停震动的方法
// 定义一个回调函数,震动结束时再次发出震动 void MyAudioServicesSystemSoundCompletionProc (SystemSoundID ssID,void *clientData) { BOOL* iShouldKeepBuzzing = clientData; if (*iShouldKeepBuzzing) { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } else { //Unregister, so we don't get called again... AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate); } } //以下为调用的代码: BOOL iShouldKeepBuzzing = YES; AudioServicesAddSystemSoundCompletion ( kSystemSoundID_Vibrate, NULL, NULL, MyAudioServicesSystemSoundCompletionProc, &iShouldKeepBuzzing ); AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
12、去掉app图标的发光效果
info.plist里增加Iconalready includes gloss effects,值设为YES
13、UIImage:stretchableImageWithLeftCapWidth:topCapHeight
这个函数是UIImage的一个实例函数,它的功能是创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数,第一个是不拉伸区域和左边框的宽度,第二个参数是不拉伸区域和上边框的宽度有时图片模糊(blur)的原因:像素没有和devicepixel对齐.使用instrument的Core
Animation可以检测这个,勾选"color misaligned images",如果图片显示为红紫色,就是没有对齐
14、UIPopoverController
如果是用presentPopoverFromBarButtonItem显示的,设备旋转时,popover可以自动调整位置;如果是用presentPopoverFromRect显示的,需要present again
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [aPopover presentPopoverFromRect:targetRect.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }
15、禁止textField和textView的复制粘贴菜单
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender { if ([UIMenuController sharedMenuController]) { [UIMenuController sharedMenuController].menuVisible = NO; } return NO; }
16、UIGestureRecognizer相关
UIGestureRecognizer 是一个具体手势的基类,提供了较为简单的手势实现方式The concrete subclasses of
UIGestureRecognizerare the following:
UITapGestureRecognizer
UIPinchGestureRecognizer
UIRotationGestureRecognizer
UISwipeGestureRecognizer
UIPanGestureRecognizer
UILongPressGestureRecognizer
一个View有GestureRecognizer又有按钮(或其它需要处理action event的控件)时,有时按钮不灵敏,解决办法:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGPoint pt = [touch locationInView:baseView]; UIView *btn = [baseView viewWithTag:TAG_MYBTN]; CGPoint ptInbtn = [baseView convertPoint:pt toView:btn]; return ![btn pointInside:ptInbtn withEvent:nil]; }
实现某个view点一下就移除时,要防止移除两次。(此方法适用于希望GestureRecognizer只执行一次的情况)
-(void)OnTapViewTobeRemoved:(UITapGestureRecognizer *)sender { if (!sender.enabled) { return; } sender.enabled = NO; [sender.view removeFromSuperview]; }
17、如何进入软件在app store 的页面
先用iTunesLink Maker找到软件在访问地址,格式为itms-apps://ax.itunes.apple.com/...,然后
#define ITUNESLINK @"itms-apps://ax.itunes.apple.com/..." NSURL *url = [NSURL URLWithString:ITUNESLINK]; if([[UIApplication sharedApplication] canOpenURL:url]){ [[UIApplication sharedApplication] openURL:url]; }
如果把上述地址中itms-apps改为http就可以在浏览器中打开了。可以把这个地址放在自己的网站里,链接到app store。
iTunes
Link Maker地址:http://itunes.apple.com/linkmaker
18、SOMEVIEW显示一段时间后消失
[self performSelector:@selector(dismissView:) withObject:someview afterDelay:2];这么写比用NSTimer代码少,不过哪种都行的,这里只是提供一种不同的方法
19、禁止程序运行时自动锁屏
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
20、改变UIAlertView背景
//UIAlertView默认是半透明的,会透出背景的内容,有时看着有些混乱。可以写个改变背景的方法changeBackground。 @interface UIAlertView (changeBK) - (void)changeBackground; @end @implementation UIAlertView (changeBK) - (void)changeBackground { for(UIView * v in [self subviews]){ if ([v isKindOfClass:[UIImageView class]]) { UIImage *theImage = [UIImage imageNamed:@"AlertView.png"]; ((UIImageView*)v).image = theImage; break; } } } @end 在[alertView show]之后或willPresentAlertView:中调用即可。 // UIAlertView *alertView = [UIAlertView alloc] init ... ... [alertView show]; [alertView changeBackground];
21、浮动提示
有时需要显示一个视图,几秒后再消失的功能,这个功能也可以写成category@interface UIView (AutoRemove) - (void)removeAfterDelay:(NSTimeInterval)time; - (void)removeImediatly; @end @implementation UIView (AutoRemove) - (void)removeAfterDelay:(NSTimeInterval)time { [self performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:time]; } - (void)removeImediatly { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(removeFromSuperview) object:nil]; [self removeFromSuperview]; } @end
22、改变UITextField的背景
@interface UITextField (changeBK) -(void)orangeBackground; @end @implementation UITextField (changeBK) -(void)orangeBackground { self.background = [[UIImage imageNamed:@"fieldBK.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5]; } @end
23、用于CALayer的动画
CALayer有默认动画效果,如果想完全用自已的,先要removeAllAnimations,再加上自设的animation。如果UIView上有一个CALayer,UIView的的内容没有更新,只有CALayer,则只重绘CALayer就可以,调用[layer setNeedsDisplay]。之前CALayer的内容会自动清除。比VC++高级,对于要更新的区域,不用手动擦除旧的24、NSPredicate
1).从数组1中过滤出数组2中没有的对象NSArray *arrayFilter = [NSArray arrayWithObjects:@"abc1", @"abc2", nil]; NSArray *arrayContent = [NSArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil]; NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter]; [arrayContent filterUsingPredicate:thePredicate];
这样arrayContent过滤出来的就是不包含arrayFilter中的所有item了。
2)、match的用法
A、简单比较
NSString *match = @"imagexyz-999.png"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF == %@", match]; NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
B、match里like的用法(类似Sql中的用法)
NSString *match = @"imagexyz*.png"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF like %@", match]; NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
C、大小写比较
[c]表示忽略大小写,[d]表示忽略重音,可以在一起使用,如下:
NSString *match = @"imagexyz*.png"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF like[cd] %@", match]; NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
D、使用正则
NSString *match = @"imagexyz-\\d{3}\\.png"; //imagexyz-123.png NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match]; NSArray *results = [directoryContents filteredArrayUsingPredicate:predicate];
总结:
1) 当使用聚合类的操作符时是可以不需要循环的
2)当使用单个比较类的操作符时可以一个循环来搞定
PS,例子 一中尝试使用[@"SELF CONTAINS %@", arrayFilter] 来过滤会挂调,因为CONTAINS时字符串比较操作符,不是集合操作符。
25、NSDictionary转NSMutableArry
NSMutableArray *objects = [myDictionary objectsForKeys:myKeys notfoundMarker:[NSNull null]]; // 这里不能用nil
26、改变UINavigationBar的背景
针对较旧的IOS,大概是IOS 4.3及以下:@implementation UINavigationBar (CustomImage) - (void)drawRect:(CGRect)rect { UIImage *image = [[UIImage imageNamed: @"navBar"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; [image drawInRect:CGRectMake(0, 0.5, self.frame.size.width, self.frame.size.height)]; } @end
针对所有版本IOS:
@implementation UINavigationBar (selBackground) -(void)setToCustomImage { if ([[UIDevice currentDevice] systemVersion].floatValue >= 5.0 ) { [self setBackgroundImage:[UIImage imageNamed:@"navBar"] forBarMetrics:UIBarMetricsDefault]; } else { self.layer.contents = (id)[UIImage imageNamed:@"navBar"].CGImage; } } @end
27、自IOS6.0,为了控制旋转,要给UINavigationController写个categary
@interface UINavigationController (Rotate) @end @implementation UINavigationController (Rotate) - (NSUInteger)supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } - (BOOL)shouldAutorotate { return [self.topViewController shouldAutorotate]; } @end //对程序里所有不希望旋转的viewController, - (BOOL)shouldAutorotate { return NO; }
28、allSubviews, allApplicationViews, pathToView
NSArray *allSubviews(UIView *aView) { NSArray *results = [aView subviews]; for (UIView *eachView in [aView subviews]) { NSArray *riz = allSubviews(eachView); if (riz) results = [results arrayByAddingObjectsFromArray:riz]; } return results; } // Return all views throughout the application NSArray *allApplicationViews() { NSArray *results = [[UIApplication sharedApplication] windows]; for (UIWindow *window in [[UIApplication sharedApplication] windows]) { NSArray *riz = allSubviews(window); if (riz) results = [results arrayByAddingObjectsFromArray: riz]; } return results; } // Return an array of parent views from the window down to the view NSArray *pathToView(UIView *aView) { NSMutableArray *array = [NSMutableArray arrayWithObject:aView]; UIView *view = aView; UIWindow *window = aView.window; while (view != window) { view = [view superview]; [array insertObject:view atIndex:0]; } return array; }
29、键盘是带按钮的pickerview
UIView *keyBoardView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 220)]; //键盘上方加工具条 UIToolbar * keyToolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 38)]; [keyToolBar setTranslucent:NO]; [keyToolBar setTintColor:RGB(212, 214, 218)]; UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; closeButton.frame = CGRectMake(260, 5.0, 50.0f, 28.0); closeButton.titleLabel.font = [UIFont fontWithName:FONT_ARIAL size:14.0]; [closeButton addTarget:self action:@selector(closeKeyboard:) forControlEvents:UIControlEventTouchUpInside]; [closeButton setTitle:T_CONFIRM forState:UIControlStateNormal]; [closeButton setBackgroundImage:[[UIImage imageNamed:@"selBack"] stretchableImageWithLeftCapWidth:8 topCapHeight:13] forState:UIControlStateNormal]; [keyToolBar addSubview:closeButton]; [keyBoardView addSubview:keyToolBar]; [keyToolBar release]; UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(keyToolBar.frame), 0, 200)]; picker.showsSelectionIndicator = YES; picker.dataSource = self; picker.delegate = self; [keyBoardView addSubview:picker]; self.pickerView = picker; [picker release]; companyTF.inputView = keyBoardView; [keyBoardView release];
30、addSubview不支持Animation
addSubView和removeFromSuperview是不支持animation的。要实现动画效果,可以利用alpha 这个变量。// 显示: floatView = [[FloatNotifyView alloc] initWithFrame:CGRectMake(35, 315, 250, 50)]; floatView.tag = TAG_FLOAT_NOTIFY; floatView.alpha = 0; [self.view addSubview:floatView]; [UIView animateWithDuration:0.2f delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ floatView.alpha = 1; } completion:^(BOOL finished) { }]; [floatView release]; // 消失: -(void)hideInfo { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideInfo) object:nil]; [UIView animateWithDuration:0.4f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ self.alpha = 0; } completion:^(BOOL finished) { [self removeFromSuperview]; }]; }
31、给keyboard增加删除按钮
数字键盘没有关闭键盘的按钮,以下代码把”Done”拆成两个按钮了。(后来觉得这个办法太麻烦了,不如在键盘上加一行工具栏,工具栏上加关闭按钮)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowOnDelay:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; - (void)keyboardWillShowOnDelay:(NSNotification *)notification { [self performSelector:@selector(keyboardWillShow:) withObject:nil afterDelay:0]; } - (void)keyboardWillShow:(NSNotification *)notification { UIView *foundKeyboard = nil; UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if (![[testWindow class] isEqual:[UIWindow class]]) { keyboardWindow = testWindow; break; } } if (!keyboardWindow) return; for (UIView *possibleKeyboard in [keyboardWindow subviews]) { //NSLog(@"%@",[possibleKeyboard description]); //iOS3 if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) { foundKeyboard = possibleKeyboard; break; } else { // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. if ([[possibleKeyboard description]hasPrefix:@"<UIPeripheralHostView"]) { BOOL didFound = NO; for (UIView *tmpView in [possibleKeyboard subviews]) { if ([[tmpView description] hasPrefix:@"<UIKeyboard"]) { foundKeyboard = tmpView; didFound = YES; break; } } if (didFound) { break; } } } } if (foundKeyboard) { UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; backButton.tag = 110; backButton.frame = CGRectMake(215, 163, 52, 53); backButton.adjustsImageWhenHighlighted = NO; UIImage *darkImage = [[UIImage imageNamed:@"dark.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; UIImage *darkCornerImage = [[UIImage imageNamed:@"darkCorner.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; UIImage *brightImage = [[UIImage imageNamed:@"bright.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; UIImage *brightCornerImage = [[UIImage imageNamed:@"brightCorner.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:0]; [backButton setBackgroundImage:darkImage forState:UIControlStateNormal]; [backButton setBackgroundImage:brightImage forState:UIControlStateHighlighted]; [backButton addTarget:self action:@selector(backButton:)forControlEvents:UIControlEventTouchUpInside]; [backButton setTitle:@"删除" forState:UIControlStateNormal]; [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted]; [foundKeyboard addSubview:backButton]; UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeCustom]; doneButton.tag = 111; doneButton.frame = CGRectMake(215+52, 163, 53, 53); doneButton.adjustsImageWhenHighlighted = NO; [doneButton setBackgroundImage:darkCornerImage forState:UIControlStateNormal]; [doneButton setBackgroundImage:brightCornerImage forState:UIControlStateHighlighted]; [doneButton addTarget:self action:@selector(doneButton:)forControlEvents:UIControlEventTouchUpInside]; [doneButton setTitle:@"隐藏" forState:UIControlStateNormal]; [doneButton setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted]; [foundKeyboard addSubview:doneButton]; } } - (void)keyboardWillHide:(NSNotification *)notification { UIView *foundKeyboard = nil; UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if (![[testWindow class] isEqual:[UIWindow class]]) { keyboardWindow = testWindow; break; } } if (!keyboardWindow) return; for (UIView *possibleKeyboard in [keyboardWindow subviews]) { //NSLog(@"%@",[possibleKeyboard description]); //iOS3 if ([[possibleKeyboard description] hasPrefix:@"<UIKeyboard"]) { foundKeyboard = possibleKeyboard; break; } else { // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. if ([[possibleKeyboard description]hasPrefix:@"<UIPeripheralHostView"]) { BOOL didFound = NO; for (UIView *tmpView in [possibleKeyboard subviews]) { if ([[tmpView description] hasPrefix:@"<UIKeyboard"]) { foundKeyboard = tmpView; didFound = YES; break; } } if (didFound) { break; } } } } if (foundKeyboard) { UIView *back = [foundKeyboard viewWithTag:110]; [back removeFromSuperview]; UIView *done = [foundKeyboard viewWithTag:111]; [done removeFromSuperview]; } }
32、设置线宽
如果是retina屏,lineWidth设为1,实际显示的宽度是2个像素,这里进行一下处理:#define SETLINEWIDTH(ctx,w)CGContextSetLineWidth(ctx, w/[UIScreen mainScreen].scale)
33、简化代码用的define
#define SETRGBSTROKECOLOR(ctx,R,G,B) CGContextSetRGBStrokeColor(context, R/255.0, G/255.0, B/255.0, 1.0) #define SETRGBFILLCOLOR(ctx,R,G,B) CGContextSetRGBFillColor(context, R/255.0, G/255.0, B/255.0, 1.0) #define _ADDOBSERVER(TITLE, SELECTOR) [[NSNotificationCenter defaultCenter] addObserver:self selector:SELECTOR name:TITLE object:nil] #define _REMOVEOBSERVER(id) [[NSNotificationCenter defaultCenter] removeObserver:id] #define _POSTNOTIFY(TITLE,OBJ,PARAM) [[NSNotificationCenter defaultCenter] postNotificationName:TITLE object:OBJ userInfo:PARAM]
34、比较版本号
NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:minRequirement options:NSNumericSearch] != NSOrderedAscending) { return YES; }else{ return NO; }
35、时间相关
NSDate需要设置calendar,使用不方便也因为服务器传过来的是time_t格式,所以我在客户端对时间的操作主要用的C语言的方法。需要注意的是,有的函数不是线程安全的,也就是说在同一个范围内调用多次时,需要调用线程安全的版本,这样的函数有:
localtime_r
asctime_r
ctime_r
gmtime_r
localtime_r
另外,可以直接给struct tm各成员变量赋值,例如(注意顺序)
struct tm tmStart ={second,minute,hour,day, mon, year};
struct tm的各成员是不能的加减的,因为超过了各变量的范围,可能出错,需要先转成time_t,再加减相应的时间
struct tm* tmp = localtime(&Time); asctime(tmp) time_t now; time(&now); struct tm * tmNow = localtime(&now); struct tm tm = {0,nMinute,nHour,tmNow->tm_mday, tmNow->tm_mon, tmNow->tm_year}; time_t _time = mktime(&tm); time_t tt1 = status.time; time_t tt2 = status2.time; struct tm tm1 = {0}; struct tm tm2 = {0}; localtime_r(&tt1, &tm1); localtime_r(&tt2, &tm2);
36、用#ifdefined控制不同版本协议的使用
- (void)Req_Login_Wh_Proc:(id)reqMsg { #if defined(EDITION_0_009_) [self Req_Login_Wh_0_009_Proc:reqMsg]; #elif defined (EDITION_0_010_) || defined(EDITION_0_011_) [self Req_Login_Wh_0_011_Proc:reqMsg]; #else [self Req_Login_Wh_0_012_Proc:reqMsg]; #endif }
37、
相关文章推荐
- ios学习--iphone开发笔记和技巧总结(原址持续更新)
- ios学习--iphone开发笔记和技巧总结(原址持续更新)
- iOS学习笔记总结二(持续更新)
- iOS学习笔记之开发实用小技巧(持续更新)
- C++ 和 汇编 混合编程幼儿园经验总结**持续更新** 学习笔记贴
- iOS学习笔记33-iOS 开发博客合集(持续更新中。。。)
- yii2学习笔记,错误总结,持续更新
- [Python] Python学习笔记之常用模块总结[持续更新...]
- IOS学习中的一些小知识点总结(持续更新)
- java学习笔记总结,持续更新中
- 【学习笔记】JMX1.4总结(持续更新)
- iOS学习笔记43-iOS9新特性和开发中常见的问题大总结
- iOS --- 总结Objective-C中经常使用的宏定义(持续更新中)
- PG学习异常总结篇:遇到并处理过的异常-持续更新
- CSS总结及兼容性问题【笔记】【持续更新】
- c++学习笔记(专注细节,持续更新)
- 我的JAVA学习笔记(记下一些容易忘记的知识点)持续更新
- iOS开发知识点总结【持续更新】
- 持续更新--Phonegap基础学习总结
- ATS缓存配置(Apache Traffic Server 学习笔记 2)——持续更新