一些好的代码

本文转自http://www.cocoachina.com/bbs/read.php?tid=122380


1、Xcode调试技巧—在系统抛出异常处设置断点

有时候我们的程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。
保守的做法是在系统抛出异常之前设置断点,具体来说是在 objc_exception_throw处设置断点。
设置步骤为:首先在 XCode 按 CMD + 6,进入断点管理窗口;
然后点击右下方的 +,增加新的 Symbolic Breakpoint,
在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。
这样在 Debug 模式下,如果程序即将抛出异常,就能在抛出异常处中断了。
比如在前面的代码中,我让 [firstObjctcrashTest]; 抛出异常。在 objc_exception_throw 处设置断点之后,程序就能在该代码处中断了,我们从而知道代码在什么地方出问题了。

2、计算UIlabel 随字体多行后的高度
+ (CGFloat)calcTextHeight:(int)textWidth text:(NSString *)text font:(int)fontSize {
    CGRect bounds, result;
    bounds = CGRectMake(0, 0, textWidth, 300);
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
    label.font = [UIFont systemFontOfSize:fontSize];
    label.text = text;
    result = [label textRectForBounds:bounds limitedToNumberOfLines:20];
    return result.size.height;
}

或者CGSize requiredSize = [introduceLabel.text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(296.0f, FLT_MAX) lineBreakMode:UILineBreakModeTailTruncation];

3、计算当前label随字体增加的长度(单行)
CGSize boundingSize = CGSizeMake(320.0f, CGFLOAT_MAX);
CGSize requiredSize = [status.user.username sizeWithFont:[UIFont boldSystemFontOfSize:13] constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat requiredWidth = requiredSize.width;

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 20, 20)];  
label.font = [UIFont boldSystemFontOfSize:20.0f];  //UILabel的字体大小  
label.numberOfLines = 0;  //必须定义这个属性,否则UILabel不会换行  
label.textColor = [UIColor whiteColor];   
label.textAlignment = NSTextAlignmentLeft;  //文本对齐方式  
[label setBackgroundColor:[UIColor redColor]];  
  
//高度固定不折行,根据字的多少计算label的宽度  
NSString *str = @"高度不变获取宽度,获取字符串不折行单行显示时所需要的长度";  
CGSize size = [str sizeWithFont:label.font constrainedToSize:CGSizeMake(MAXFLOAT, label.frame.size.height)];  
NSLog(@"size.width=%f, size.height=%f", size.width, size.height);  
//根据计算结果重新设置UILabel的尺寸  
[label setFrame:CGRectMake(0, 10, size.width, 20)];  
label.text = str;  
  
[self.view addSubview:label];  
[label release];  


4、view控件加边框
profileImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[profileImageButton.layer setMasksToBounds:YES];
[profileImageButton.layer setCornerRadius:4.0]; //设置矩形四个圆角半径
[profileImageButton.layer setBorderWidth:1.0];   //边框宽度
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorref = CGColorCreate(colorSpace,(CGFloat[]){225.0/255.0, 225.0/255.0, 225.0/255.0, 1.0 });
[profileImageButton.layer setBorderColor:colorref];//边框颜色 

单独设置圆角
[iconImage.layer setCornerRadius:4.0];
[iconImage setClipsToBounds:YES];

5、时区返回格式为数字(-12—+12)   
-(NSString *)getTimeZone{ 
    NSString *zone = [[NSTimeZone systemTimeZone] description];//Europe/Berlin//       America/New_York//   Asia/Harbin
                                                                               //这三个可以用来测试exp:NSString *zone = [[NSTimeZone timeZoneWithName:@"America/New_York"] description];
    NSString *time = [[zone componentsSeparatedByString:@"offset "] objectAtIndex:1];
    int inv = [time intValue];
    int result = inv / (60 * 60);
    if (result>0) {
        return [NSString stringWithFormat:@"+%d", result];
    }
    return [NSString stringWithFormat:@"%d", result];
}

6、判定输入框不为空格以及空
   NSString *_textField=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([_textField length] == 0) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:@"评论内容不能为空!" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alertView show];
        return NO;
    }

7、根据当前键盘的高度来设置UITextField的位置
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)keyboardWillShow:(id)sender {
    CGRect keyboardFrame;
    [[[((NSNotification *)sender) userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
    CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame);
    [self.textImageView setFrame:CGRectMake(0, 416-keyboardHeight, 320, 45)];
}
8、设置label ,imageview,等点击时事件
    UITapGestureRecognizer *imageTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImage:)];
   // [imageView setUserInteractionEnabled:YES]; 如果不能点击,设置可编辑
    [imageView addGestureRecognizer:imageTap];

9、判断剩余字数(字母数字符号两个算一个汉字)
-(int)charNumber:(NSString *)strTemp
{
    int strLength =1;
    char *p =(char *) [strTemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0; i<[strTemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++)
    {
        if (*p) {
            p++;
            strLength++;
        }
        else{
            p++;
        }
    }
    return strLength/2;
}
10、UIWebView加载gif图片  ——这样可以解决gif图片不能下载到本地加载,使用SDWebImage down也出现界面不流畅,卡的问题
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [homeTableCell getImageWidth:funnyPic], [homeTableCell getImageHeight:funnyPic])];
        webView.backgroundColor = [UIColor clearColor];
       // webView.scalesPageToFit = NO; 这一句我一直没搞清楚,有时对,有时不对的,注释了吧
        //禁止webView的滑动 这样写主要是因为5.0以前的系统不能直接获取到webView.scrollView
        [(UIScrollView *)[[webView subviews] objectAtIndex:0] setBounces:NO];
// 不让有白色的边,这个margin是必须的   
        NSString *html = [NSString stringWithFormat:@"<html><body style=\"margin: 0px;\"><img src=\"%@\"></body></html> ",funnyPic.imageUrl];
        [webView loadHTMLString:html baseURL:nil];
        [imageView addSubview:webView];

11、插入加载更多 tableview reloadData闪的问题
        if (requestArray && [requestArray count] > 0) {
            int cellCount = [requestArray count];//获取一共有几行
            NSMutableArray *indexArray = [[NSMutableArray alloc]initWithCapacity:10];
            int numCountNow = [self.tableView numberOfRowsInSection:0];
            for (; cellCount > 0; cellCount--) {
                NSIndexPath *path = [NSIndexPath indexPathForRow:numCountNow + cellCount - 1 inSection:0];
                [indexArray addObject:path];
            }
            [self.tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
        }
12、Image 加载16进制的 图片(编译成freamwork的时候不能直接加载png图片,要转化)
首先,使用UltraEdit把图片转化为16进制
static const char _playerPause_icon [] = {
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
    0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0xF6, 0x64,
    0x9C, 0x00, 0x00, 0x00, 0x39, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8D, 0x63, 0x64, 0x60, 0x60, 0x38,
    0xC3, 0x80, 0x1D, 0x98, 0x60, 0x11, 0xC3, 0xAA, 0x96, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1, 0x4A,
    0x30, 0x32, 0x32, 0xA2, 0x8B, 0xE1, 0x52, 0xCB, 0x84, 0xC3, 0x15, 0x24, 0x81, 0x51, 0x43, 0x46,
    0x0D, 0x19, 0x35, 0x64, 0xD4, 0x90, 0x51, 0x43, 0x46, 0x0D, 0xA1, 0xA7, 0x21, 0x00, 0xDD, 0x84,
    0x09, 0xFD, 0x6B, 0x3C, 0x1F, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42,
    0x60, 0x82
};
然后加载 
[playButton setImage:[UIImage imageWithData:[NSData dataWithBytes:_playerPause_icon length:sizeof(_playerPause_icon)/sizeof(char)]] forState:UIControlStateNormal];

13、倒计时(剩余时间)
- (void)timerFireMethod:(NSTimer*)theTimer{
     
    id obj = [theTimer userInfo];
    NSDateFormatter *f1 = [[NSDateFormatter alloc] init];
    [f1 setDateFormat:@"yyyy-MM-dd HH:mm:ss.S"];
     
    NSDate *theDay = [f1 dateFromString:(NSString*)obj];
    [f1 release];

    NSCalendar *cal = [NSCalendar currentCalendar];//定义一个NSCalendar对象
     
    NSDate *today = [NSDate date];//得到当前时间
     
    //用来得到具体的时差
    unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *d = [cal components:unitFlags fromDate:today toDate:theDay options:0];
     
    NSString *countdown = [NSString stringWithFormat:@"%d日%d时%d分%d秒", [d month],[d day], [d hour], [d minute], [d second]];
     
    self.timeLabel.text = countdown;
    return ;
     
}

14、九宫格或者其他类型的坐标设置
        frame.size.width = 60;//设置按钮坐标及大小 
        frame.size.height = 60;
        frame.origin.x = (i%3)*(60 + 32)+40;
        frame.origin.y = floor(i/3)*(60 + 24)+60;

15、appstore的几个跳转
     1)跳转到应用: http://itunes.apple.com/cn/app/id566839843?mt=8
     2)跳转到评论界面:        
        NSString *m_appleID = @"566839843";
        NSString *str = [NSString stringWithFormat:@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@",m_appleID];
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];

16、显示多语言
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *localLangyage = [languages objectAtIndex:0];

    if ([localLangyage isEqualToString:@"zh-Hans"]) {……}

17、随机
+ (NSString *)generateNonce {
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    NSString *returnString = [( NSString *)string copy];
    CFRelease(string);
    CFRelease(theUUID);
    return returnString;
}

18、//刷新相应的cell
- (void)getNewPersonCount:(NSNotification*)notifation{
    int refreshIndex = [[notifation object]intValue];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:refreshIndex inSection:0];
    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
}

            //[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
            //[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
            //[tableView deselectRowAtIndexPath:indexPath animated:YES];
19、//存储到本地txt中
- (void)editMenuOfBook{
    
    NSString *filePath = @"/Users/Henghai/Desktop/BookReader/books/三国演义";
    NSString *savefilePath = @"/Users/Henghai/Desktop/save.txt";
    
    NSFileManager *fileManager =[NSFileManager defaultManager];
    
    NSError *err = nil;
    NSArray *fileListOfFilePath = [fileManager contentsOfDirectoryAtPath:filePath error:&err];
    int fileCount = [fileListOfFilePath count];
    if (fileCount > 0) {
        NSString* str = [self joinString:fileListOfFilePath sep:@"\n"];
        NSError *err = nil;
        [str writeToFile:savefilePath atomically:YES encoding:NSUTF8StringEncoding error:&err];
    }
}

- (NSString*) joinString:(NSArray*)array sep:(NSString*)sep
{
    NSMutableString* str = [[NSMutableString alloc] initWithCapacity:[array count] * 2];
    
    bool isFirst = YES;
    
    for (NSString* s in array)
    {
        if (isFirst)
        {
            isFirst = NO;
        }
        else
        {
            [str appendString:sep];
        }
        
        [str appendString:[NSString stringWithFormat:@"<page>%@</page>",s]];
    }
    
    return str;
}

20、Data that can be recreated but must persist for proper functioning of your app - or because customers expect it to be available for offline use - should be marked with the "do not back up" attribute. 

想放到documents目录的话 设置do not back up属性就行了

[[NSFileManager defaultManager] createDirectoryAtPath:temp 
                          withIntermediateDirectories:NO
                                           attributes:nil
                                                error:nil];
NSURL *dbURLPath = [NSURL URLWithString:temp];
[self addSkipBackupAttributeToItemAtURL:dbURLPath]; 

#include <sys/xattr.h>
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];

    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    return result == 0;
}

21、字符串截取
  (1).截取字符串

NSString*string =@"sdfsfsfsAdfsdf";
string = [string substringToIndex:7];//截取下标7之后的字符串
NSLog(@"截取的值为:%@",string);
[string substringFromIndex:2];//截取下标2之前的字符串
NSLog(@"截取的值为:%@",string);


  (2).匹配字符串
NSString*string =@"sdfsfsfsAdfsdf";
NSRangerange = [stringrangeOfString:@"f"];//匹配得到的下标
NSLog(@"rang:%@",NSStringFromRange(range));
string = [string substringWithRange:range];//截取范围类的字符串
NSLog(@"截取的值为:%@",string);


  (3).分隔字符串
NSString*string =@"sdfsfsfsAdfsdf";

NSArray *array = [string componentsSeparatedByString:@"A"]; //从字符A中分隔成2个元素的数组
NSLog(@"array:%@",array); //结果是adfsfsfs和dfsdf

22.两次的间隔时间判断
//防止一直刷新积分 规定两次间隔20秒
NSTimeInterval _storedTimeInterval;
初始化:NSDate * nowDate = [NSDate date];
    _storedTimeInterval = [nowDate timeIntervalSince1970];

判断:NSDate * nowDate = [NSDate date];
            NSTimeInterval now = [nowDate timeIntervalSince1970];
            int disValue = now - _storedTimeInterval;
           if (disValue >= 20 ) {
           _storedTimeInterval = now;
          //XXXXXX处理
          }
23、开启新线程

[NSThread detachNewThreadSelector:@selector(threadFunction) toTarget:self withObject:nil];

- (void)threadFunction{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingString:@"/test.txt"];

NSFileManager *fileManager =[NSFileManager defaultManager];

    unsigned long long textSize = 0;
    textSize = [[[fileManager attributesOfItemAtPath:path error:nil] objectForKey:NSFileSize] unsignedLongLongValue];

    while (textSize == 0) {
        [[NSRunLoop currentRunLoop] runMode:UITrackingRunLoopMode beforeDate:[NSDate distantFuture]];
        textSize = [[[fileManager attributesOfItemAtPath:path error:nil] objectForKey:NSFileSize] unsignedLongLongValue];


    }
}


首先是Run Loop的部分概念,它的作用就是循环、处理事件。具体来说有两个方面: 1. 定时启动任务(一般用和Timer协作);2. 处理事件。
在单线程的app中,不需要注意Run Loop,但不代表没有。程序启动时,系统已经在主线程中加入了Run Loop。它保证了我们的主线程在运行起来后,就处于一种“等待”的状态(而不像一些命令行程序一样运行一次就结束了),这个时候如果有接收到的事件(Timer的定时到了或是其他线程的消息),就会执行任务,否则就处于休眠状态。
如果我们要写多线程的程序,可能就需要自己来管理Run Loop。
RunMode: NSDefaultRunLoopMode,可以把这个理解为一个”过滤器“,我们可以只对自己关心的事件进行监视。一般NSDefaultRunLoopMode是最常用的。
启动run loop的方法就是 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantPast]] ,它的说明如下:
Runs the loop once, blocking for input in the specified mode until a given date.
启动run loop一次,在特定的run loop mode下等待输入。
如果没有附加input source或是timer,或是过limitDate,run loop就会退出,并且方法返回NO。
下来是Run Loop的使用场合:
1. 使用port或是自定义的input source来和其他线程进行通信
2. 在线程(非主线程)中使用timer
3. 使用 performSelector...系列(如performSelectorOnThread, ...)
4. 使用线程执行周期性工作
run loop不需要创建,在线程中只需要调用[NSRunLoop currentRunLoop]就可以得到
假设我们想要等待某个异步方法的回调。比如connection。如果我们的线程中没有启动run loop,是不会有效果的(因为线程已经运行完毕,正常退出了)。我们可以用一个条件来运行run loop
BOOL done = NO;
do
{
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]
}
while(!done);
这样就可以一直进行等待,直到在别的位置将done置为YES,表示任务完成。(转自 http://www.cocoachina.com/bbs/read.php?tid=7851&keyword=NSRunLoop   7楼 )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值