Xcode调试技巧

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;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:@"",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];}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:@"%@",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- (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楼)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,107评论 29 470
  • 作者原文链接:点这里 一、普通操作: 1.打断点 当然也还可以监视某个变量! 在对象视图中,右键某个对象,点击“W...
    DestinyFighter_阅读 1,588评论 0 4
  • 剑未配好,出门已是江湖。 最近一直没有更新简书是因为在开发和测试阶段,有任务,没有进行学习,不过在做任务的时...
    和珏猫阅读 8,113评论 9 75
  • 前言 Xcode调试(debug)是每位IOS开发者经常做的事,很基础也很重要,学到一些调试技巧无疑会给工作带来很...
    xmy1012阅读 1,452评论 0 1
  • 《我的前半生》剧情的走向,越来越狗血了。各种玛丽苏剧情轮番上演,罗子君主角光环顶破天,一出“霸道总裁爱上我”的大戏...
    不等于阅读 685评论 0 2