.symbols ios_ios opencv symbols - CSDN
  • Symbols是什么东西呢?虽然我对它没有深入的了解,但是大概知道它的作用。摘抄《深入理解计算机系统》里的一些描述: 一个典型的ELF可重定位目标文件包含下面几个节: ... ... .symtab:一个符号表,它存放在...

    其实被这个问题困扰了好久,不过秉承着三分钟热度的新年新气象,还是要多弄懂一点(⊙_⊙)ゞ

    Symbols是什么东西呢?虽然我对它没有深入的了解,但是大概知道它的作用。摘抄《深入理解计算机系统》里的一些描述:

    一个典型的ELF可重定位目标文件包含下面几个节:
    ... ...
    .symtab:一个符号表,它存放在程序中定义和引用的函数和全局变量信息。一些程序员错误地认为必须通过-g选项来编译程序才能得到符号表信息。实际上,每个可重定位目标文件在.symtab中都有一张符号表。然而,和编译器中的符号表不同,.symtab符号表不包含局部变量的条目。
    ... ...
    .debug:一个调试符号表,其条目是程序中定义的局部变量和类型定义,程序中定义和引用的全局变量,以及原始的C源文件。只有以-g选项调用编译驱动程序时才会得到这张表。
    ... ...

    为了构造可执行文件,链接器必须完成两个主要任务:

    • 符号解析(symbol resolution)。目标文件定义和引用符号。符号解析的目的是将每个符号引用刚好和一个符号定义联系起来。
    • 重定位(relocation)。编译器和汇编器生成从地址0开始的代码和数据节。链接器通过把每个符号定义与一个存储器位置联系起来,然后修改所有对这些符号的引用,使得它们指向这个存储器位置,从而重定位这些节。

    Objective-C有一些自己的生成符号的规则,比如文档中有提到:

    The dynamic nature of Objective-C complicates things slightly. Because the code that implements a method is not determined until the method is actually called, Objective-C does not define linker symbols for methods. Linker symbols are only defined for classes.

    Objective-C不会为方法定义链接符号,只会为类定义链接符号。

    可以在终端中用nm命令查看一个可重定位文件或可执行文件的符号表,其中加上-a参数可以显示包括调试符号在内的所有符号。

    合理的选择与symbols有关的设置选项,可以缩减app的大小,一定程度上能阻碍与源代码有关的信息被攻击者获得。Xcode的build setting中,有不少与symbols有关,现在我来依次试验这几个设置选项,了解一下它们的具体作用。

    刚开始的时候,我使用Xcode7.2.1新建了一个工程,以下试验均在run和DEBUG模式下进行。


    Generate Debug Symbols [GCC_GENERATE_DEBUGGING_SYMBOLS]


    在Xcode7.2.1中,Generate Debug Symbols这个设置在DEBUG和RELEASE下均默认为YES

    官方文档对这个设置的说明:

    Enables or disables generation of debug symbols. When debug symbols are enabled, the level of detail can be controlled by the build 'Level of Debug Symbols' setting. 

    调试符号是在编译时生成的。在Xcode中查看构建过程,可以发现,当Generate Debug Symbols选项设置为YES时,每个源文件在编译成.o文件时,编译参数多了-g-gmodules两项。但链接等其他的过程没有变化。

    Clang文档对-g的描述是:

    Generate complete debug info.

    Generate Debug Symbols设置为YES时,编译产生的.o文件会大一些,当然最终生成的可执行文件也大一些。

    Generate Debug Symbols设置为NO的时候,在Xcode中设置的断点不会中断。但是在程序中打印[NSThread callStackSymbols],依然可以看到类名和方法名,比如:

    ** 0   XSQSymbolsDemo                      0x00000001000667f4 -[ViewController viewDidLoad] + 100**

    在程序崩溃时,也可以得到带有类名和方法名的函数调用栈


    现在把Generate Debug Symbols设置回YES,开始试验下一个设置。


    Debug Information Level [CLANG_DEBUG_INFORMATION_LEVEL]


    在Xcode 7.2.1中,Debug Information Level的默认值为Compiler default,还有一个选项是Line tables only

    官方文档的描述是:

    Toggles the amount of debug information emitted when debug symbols are enabled. This can impact the size of the generated debug information, which can matter in some cases for large projects (such as when using LTO). 

    当我把Debug Information Level设置为Line tables only的时候,然后构建app,每个源文件在编译时,都多了一个编译参数:-gline-tables-only

    Clang的文档中这样解释-gline-tables-only

    Generate line number tables only.
    This kind of debug info allows to obtain stack traces with function names, file names and line numbers (by such tools as gdb or addr2line). It doesn’t contain any other data (e.g. description of local variables or function parameters).

    这种类型的调试信息允许获得带有函数名、文件名和行号的函数调用栈,但是不包含其他数据(比如局部变量和函数参数)。

    所以当Debug Information Level设置为Line tables only的时候,断点依然会中断,但是无法在调试器中查看局部变量的值:


    现在把Debug Information Level设置回Compiler default,然后试验下一个设置。


    Strip Linked Product [STRIP_INSTALLED_PRODUCT]


    在Xcode7.2.1中,Strip Linked Product在DEBUG和RELEASE下均默认为YES

    这是一个让我困惑了很久的设置选项。当我把这一设置选项改为NO的时候,最终构建生成的app大小没有任何变化,这让我觉得很奇怪。

    原来,Strip Linked Product也受到Deployment Postprocessing设置选项的影响。在Build Settings中,我们可以看到,Strip Linked Product是在Deployment这栏中的,而Deployment Postprocessing相当于是Deployment的总开关。
    Xcode7.2.1中,Deployment Postprocessing在DEBUG和RELEASE下均默认为NO

    现在我们把Deployment Postprocessing设置为YES,对比Strip Linked Product设为YESNO的这两种情况,发现当Strip Linked Product设为YES的时候,app的构建过程多了这样两步:

    1. 在app构建的开始,会生成一些.hmap辅助文件;(为什么会多出这一步我好像还不太清楚)
    2. 在app构建的末尾,会执行Strip操作。


    Strip Linked Product设为YES的时候,运行app,断点不会中断,在程序中打印[NSThread callStackSymbols]也无法看到类名和方法名:

    ** 0   XSQSymbolsDemo                      0x000000010001a7f4 XSQSymbolsDemo + 26612**

    而在程序崩溃时,函数调用栈中也无法看到类名和方法名,注意右上角变成了unnamed_function:


    继续保持Strip Linked ProductDeployment PostprocessingYES,下面来看看Strip Style设置选项。


    Strip Style [STRIP_STYLE]


    在Xcode7.2.1中,Strip Style在DEBUG和RELEASE下均默认All Symbols

    官方文档中对Strip Style的描述:

    Defines the level of symbol stripping to be performed on the linked product of the build. The default value is defined by the target's product type. [STRIP_STYLE]

    All Symbols - Completely strips the binary, removing the symbol table and relocation information. [all, -s]
    Non-Global Symbols - Strips non-global symbols, but saves external symbols. [non-global, -x]
    Debugging Symbols - Strips debugging symbols, but saves local and global symbols. [debugging, -S]

    选择不同的Strip Style时,app构建末尾的Strip操作会被带上对应的参数。

    如果选择debugging symbols的话,函数调用栈中,类名和方法名还是可以看到的。


    如果我们构建的不是一个app,而是一个静态库,需要注意,静态库是不可以strip all的。这时构建会失败。想想符号在重定位时的作用,如果构建的静态库真的能剥离所有符号,那么它也就没法被链接了。

    现在我们保持Deployment PostprocessingYESStrip Linked Product改回NOStrip Style改回All Symbols,接下来看下一个设置。


    Strip Debug Symbols During Copy [COPY_PHASE_STRIP]


    网上有很多文章,以为Strip Debug Symbols During Copy开启的时候,app中的调试符号会被剥离掉。我感觉他们混淆了Strip Linked ProductStrip Debug Symbols During Copy的用法。

    文档上的描述是:

    Activating this setting causes binary files which are copied during the build (e.g., in a Copy Bundle Resources or Copy Files build phase) to be stripped of debugging symbols. It does not cause the linked product of a target to be stripped (use Strip Linked Product for that).

    Strip Debug Symbols During Copy中的During Copy是什么意思呢?我觉得可能是app中引入的某些类型的库,在app的构建过程中需要被复制一次。虽然我暂时没找全究竟什么样的“库”需要在app构建时被复制,但是我发现,当app中包含extension或者watch app的时候,构建过程中会有Copy的步骤:


    当我将app(而非extension)的Strip Debug Symbols During Copy设置为YES之后,在这句copy的命令中会多出-strip-debug-symbols参数。

    但是这里,strip并不能成功,并且出现了warning:

    warning: skipping copy phase strip, binary is code signed: /Users/xsq/Library/Developer/Xcode/DerivedData/XSQSymbolsDemo-cysszdsykroyyddkvvyffgboglvo/Build/Products/Debug-iphoneos/Today.appex/Today

    这似乎是由于app中的today extention已经经过了code sign,导致无法被篡改引起的警告。

    那么如果略过code sign的过程,是否就能成功strip呢?我想使用模拟器调试可以略过code sign过程,于是便在模拟器上试了试。果然这个warning消失了。

    Strip Debug Symbols During Copy设置为YES时,打开对应.app文件的“显式包内容”,可以看到,/PlugIns/Today.appex文件的大小变小了。(不过这些只能在使用模拟器时奏效)

    Strip Debug Symbols During Copy置为YES的时候,today extension中的断点将不会中断,但是打印[NSThread callStackSymbols]时的类名和方法名还是可以看见的。

    现在我们把Strip Debug Symbols During Copy设置回NO,来看看下一个设置。


    Debug Information Format [DEBUG_INFORMATION_FORMAT]


    Xcode7.2.1中,Debug Information Format在DEBUG下默认为DWARF,在RELEASE下默认为DWARF with dSYM File

    官方文档的解释是:

    This setting controls the format of debug information used by the developer tools. [DEBUG_INFORMATION_FORMAT]

    DWARF - Object files and linked products will use DWARF as the debug information format. [dwarf]
    DWARF with dSYM File - Object files and linked products will use DWARF as the debug information format, and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). [dwarf-with-dsym]

    Debug Information FormatDWARF with dSYM File的时候,构建过程中多了一步Generate dSYM File:



    最终产出的文件也多了一个dSYM文件。

    不过,既然这个设置叫做Debug Information Format,所以首先得有调试信息。如果此时Generate Debug Symbols选择的是NO的话,是没法产出dSYM文件的。

    dSYM文件的生成,是在Strip等命令执行之前。所以无论Strip Linked Product是否开启,生成的dSYM文件都不会受影响。

    不过正如文档中所说,无法为静态库生成dSYM文件。即便为给一个静态库的Debug Information Format设置为DWARF with dSYM File,构建过程中依然不会有生成dSYM文件的步骤。


    一种配置方案


    了解了每个设置的意思,个人觉得对于一个普通的app来说可以这样配置这些设置:

    • Generate Debug Symbols:DEBUG和RELEASE下均设为YES(和Xcode默认一致);
    • Debug Information Level:DEBUG和RELEASE下均设为Compiler default(和Xcode默认一致);
    • Deployment Postprocessing:DEBUG下设为NO,RELEASE下设为YES,这样RELEASE模式下就可以去除符号缩减app的大小(但是似乎设置为YES后,会牵涉一些和bitcode有关的设置,对于bitcode暂时还不太了解(´・_・`));
    • Strip Linked Product:DEBUG下设为NO,RELEASE下设为YES,用于RELEASE模式下缩减app的大小;
    • Strip Style:DEBUG和RELEASE下均设为All Symbols(和Xcode默认一致);
    • Strip Debug Symbols During Copy:DEBUG下设为NO,RELEASE下设为YES
    • Debug Information Format:DEBUG下设为DWARF,RELEASE下设为DWARF with dSYM File,dSYM文件需要用于符号化crash log(和Xcode默认一致);

    参考

    深入理解计算机系统
    Build Setting Reference
    Skipping Copy Phase Strip
    xcode build settings for debug symbol
    Clang Compiler User’s Manual
    Symbolification: Shipping Symbols
    Technical Q&A QA1490

    某天,我看了公司的项目的设置,发现Deployment Postprocessing这项在DEBUG和RELEASE下均为NO,让我有些奇怪,难道公司的项目没有滤去调试符号?

    于是我archive了一下,发现,在archive的过程中,其实是跑了strip的命令的,让我有点吃惊。这说明run和archive的构建过程是不同的。

    查了官方文档,暂时没能查到run和archive到底有哪里不同,但是这里对ACTION的解释让我有些在意。对ACTION的设置会影响到Deployment Postprocessing的默认值,即当$ACTION = install的时候,Deployment Postprocessing默认为YES

    展开全文
  • ios: Undefined symbols

    2019-05-01 22:47:14
    ios: Undefined symbols ios universal build 2019.4.30 背景 用xcode 做了一个iphone ui demo工程,它依赖另一个 tvm_model.framework 工程. demo内使用了 tvm_model.framework内的c++类 TVMModel. 问题 编译demo...

    ios: Undefined symbols

    ios universal build

    2019.4.30

    背景

    用xcode 做了一个iphone ui demo工程,它依赖另一个 tvm_model.framework 工程.

    demo内使用了 tvm_model.framework内的c++类 TVMModel.

    问题

    编译demo工程,Debug能编译通过,Release总是报告错误:
    Undefined symbols for architecture arm64/armv7:
    OBJC_CLASS$_TVMModel”, referenced from: objc-class-ref in AppDelegate.o

    调查过程

    在xcode tvm_model工程设置内,对比了Debug和Release区别,感觉有3个选项和编译有关:

    Options Debug Release
    GCC_GENERATE_DEBUGGING_SYMBOLS YES NO
    GCC_OPTIMIZATION_LEVEL 0 s
    GCC_SYMBOLS_PRIVATE_EXTERN NO YES
    Build Active Architecture Only YES NO

    把Release的4个配置项,挨个修改尝试,发现GCC_SYMBOLS_PRIVATE_EXTERN从YES改成NO,demo就能编译成功.
    把Build Active Architecture Only从NO改成YES也能成功。

    分析

    定位到原因,上网搜索了一下,GCC_SYMBOLS_PRIVATE_EXTERN对应的是:
    Build settings 内的 Symbols Hidden By Default.

    从字面意思看,是把符号隐藏起来(能让编译结果缩小很多).

    Release模式,所有符号被隐藏起来了,那么demo就连接不到tvm_model内的类了.

    解决办法

    只要把需要导出的类,明确的告诉编译器就行了。

    具体参见这个链接制作framework

    还有一个问题,就是demo连接的device是i386的模拟器,而tvm_model.framework只编译了armv7/armv8平台的代码。

    必须把tvm_model工程的Build Active Architecture Only,设置成YES,这样才能和demo一样,编译出模拟器需要的i386代码。

    展开全文
  • iOS开发零碎知识点

    2018-04-02 17:28:41
    记录一些常用和不常用的iOS知识点,防止遗忘丢失。(来源为收集自己项目中用到的或者整理看到博客中的知识点),如有错误,欢迎大家批评指正;如有好的知识点,也欢迎大家联系我,添加上去。谢谢! 欢迎大家关注...

    记录一些常用和不常用的iOS知识点,防止遗忘丢失。(来源为收集自己项目中用到的或者整理看到博客中的知识点),如有错误,欢迎大家批评指正;如有好的知识点,也欢迎大家联系我,添加上去。谢谢!

    欢迎大家关注文明的iOS开发公众号:
    方式1、搜索:“iOS开发by文明”
    方式2、扫描下方二维码
    这里写图片描述

    一、调用代码使APP进入后台,达到点击Home键的效果。(私有API)

        [[UIApplication sharedApplication] performSelector:@selector(suspend)];
    

    suspend的英文意思有:暂停; 悬; 挂; 延缓;

    二、带有中文的URL处理。

    大概举个例子,类似下面的URL,里面直接含有中文,可能导致播放不了,那么我们要处理一个这个URL,因为他太操蛋了,居然用中文。

    http://static.tripbe.com/videofiles/视频/我的自拍视频.mp4
    NSString *path  = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,                                                                                                          (__bridge CFStringRef)model.mp4_url,                                                                         CFSTR(""),                                                                                                    CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    

    三、获取UIWebView的高度
    个人最常用的获取方法,感觉这个比较靠谱

    - (void)webViewDidFinishLoad:(UIWebView *)webView  {  
        CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];  
        CGRect frame = webView.frame;  
        webView.frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, height);  
    }  
    

    四、给UIView设置图片(UILabel一样适用)

    • 第一种方法:
      利用的UIView的设置背景颜色方法,用图片做图案颜色,然后传给背景颜色。

      UIColor *bgColor = [UIColor colorWithPatternImage: [UIImage imageNamed:@"bgImg.png"];
              UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
      [myView setBackGroundColor:bgColor];
      
    • 第二种方法:

      UIImage *image = [UIImage imageNamed:@"yourPicName@2x.png"];
      yourView.layer.contents = (__bridge id)image.CGImage;
      //设置显示的图片范围
      yourView.layer.contentsCenter = CGRectMake(0.25,0.25,0.5,0.5);//四个值在0-1之间,对应的为x,y,width,height。
      

    五、去掉UITableView多余的分割线

    yourTableView.tableFooterView = [UIView new];
    

    六、调整cell分割线的位置,两个方法一起用,暴力解决,防脱发

    -(void)viewDidLayoutSubviews {
    
        if ([self.mytableview respondsToSelector:@selector(setSeparatorInset:)]) {
            [self.mytableview setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    
        }
        if ([self.mytableview respondsToSelector:@selector(setLayoutMargins:)])  {
            [self.mytableview setLayoutMargins:UIEdgeInsetsMake(0, 0, 0, 0)];
        }
    
    }
    
    #pragma mark - cell分割线
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if ([cell respondsToSelector:@selector(setSeparatorInset:)]){
            [cell setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
        }
        if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
            [cell setLayoutMargins:UIEdgeInsetsMake(0, 0, 0, 0)];
        }
    }
    

    七、UILabel和UIImageView的交互userInteractionEabled默认为NO。那么如果你把这两个类做为父试图的话,里面的所有东东都不可以点击哦。曾经有一个人,让我帮忙调试bug,他调试很久没搞定,就是把WMPlayer对象(播放器对象)放到一个UIImageView上面。这样imageView addSubView:wmPlayer 后,播放器的任何东东都不能点击了。userInteractionEabled设置为YES即可。

    八、UISearchController和UISearchBar的Cancle按钮改title问题,简单粗暴

    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
    {
        searchController.searchBar.showsCancelButton = YES;
        UIButton *canceLBtn = [searchController.searchBar valueForKey:@"cancelButton"];
        [canceLBtn setTitle:@"取消" forState:UIControlStateNormal];
        [canceLBtn setTitleColor:[UIColor colorWithRed:14.0/255.0 green:180.0/255.0 blue:0.0/255.0 alpha:1.00] forState:UIControlStateNormal];
        searchBar.showsCancelButton = YES;
        return YES;
    }
    

    九、UITableView收起键盘何必这么麻烦
    一个属性搞定,效果好(UIScrollView同样可以使用)
    以前是不是觉得[self.view endEditing:YES];很屌,这个下面的更屌。
    yourTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

    另外一个枚举为UIScrollViewKeyboardDismissModeInteractive,表示在键盘内部滑动,键盘逐渐下去。

    十、NSTimer
    1、NSTimer计算的时间并不精确
    2、NSTimer需要添加到runLoop运行才会执行,但是这个runLoop的线程必须是已经开启。
    3、NSTimer会对它的tagert进行retain,我们必须对其重复性的使用intvailte停止。target如果是self(指UIViewController),那么VC的retainCount+1,如果你不释放NSTimer,那么你的VC就不会dealloc了,内存泄漏了。

    十一、UIViewController没用大小(frame)
    经常有人在群里问:怎么改变VC的大小啊?
    瞬间无语。(只有UIView才能设置大小,VC是控制器啊,哥!)

    十二、用十六进制获取UIColor(类方法或者Category都可以,这里我用工具类方法)

    + (UIColor *)colorWithHexString:(NSString *)color
    {
        NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    
        // String should be 6 or 8 characters
        if ([cString length] < 6) {
            return [UIColor clearColor];
        }
    
        // strip 0X if it appears
        if ([cString hasPrefix:@"0X"])
            cString = [cString substringFromIndex:2];
        if ([cString hasPrefix:@"#"])
            cString = [cString substringFromIndex:1];
        if ([cString length] != 6)
            return [UIColor clearColor];
    
        // Separate into r, g, b substrings
        NSRange range;
        range.location = 0;
        range.length = 2;
    
        //r
        NSString *rString = [cString substringWithRange:range];
    
        //g
        range.location = 2;
        NSString *gString = [cString substringWithRange:range];
    
        //b
        range.location = 4;
        NSString *bString = [cString substringWithRange:range];
    
        // Scan values
        unsigned int r, g, b;
        [[NSScanner scannerWithString:rString] scanHexInt:&r];
        [[NSScanner scannerWithString:gString] scanHexInt:&g];
        [[NSScanner scannerWithString:bString] scanHexInt:&b];
    
        return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
    }
    

    十三、获取今天是星期几

    + (NSString *) getweekDayStringWithDate:(NSDate *) date
    {
        NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; // 指定日历的算法
        NSDateComponents *comps = [calendar components:NSWeekdayCalendarUnit fromDate:date];
    
        // 1 是周日,2是周一 3.以此类推
    
        NSNumber * weekNumber = @([comps weekday]);
        NSInteger weekInt = [weekNumber integerValue];
        NSString *weekDayString = @"(周一)";
        switch (weekInt) {
            case 1:
            {
                weekDayString = @"(周日)";
            }
                break;
    
            case 2:
            {
                weekDayString = @"(周一)";
            }
                break;
    
            case 3:
            {
                weekDayString = @"(周二)";
            }
                break;
    
            case 4:
            {
                weekDayString = @"(周三)";
            }
                break;
    
            case 5:
            {
                weekDayString = @"(周四)";
            }
                break;
    
            case 6:
            {
                weekDayString = @"(周五)";
            }
                break;
    
            case 7:
            {
                weekDayString = @"(周六)";
            }
                break;
    
            default:
                break;
        }
        return weekDayString;
    
    }
    

    十四、UIView的部分圆角问题

    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(120, 10, 80, 80)];
    view2.backgroundColor = [UIColor redColor];
    [self.view addSubview:view2];
    
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view2.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view2.bounds;
    maskLayer.path = maskPath.CGPath;
    view2.layer.mask = maskLayer;
    //其中,
    byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
    //指定了需要成为圆角的角。该参数是UIRectCorner类型的,可选的值有:
    * UIRectCornerTopLeft
    * UIRectCornerTopRight
    * UIRectCornerBottomLeft
    * UIRectCornerBottomRight
    * UIRectCornerAllCorners
    

    从名字很容易看出来代表的意思,使用“|”来组合就好了。

    十五、设置滑动的时候隐藏navigationBar

    navigationController.hidesBarsOnSwipe = Yes;
    

    十六、iOS画虚线
    记得先 QuartzCore框架的导入

    #import <QuartzCore/QuartzCore.h>
    
    CGContextRef context =UIGraphicsGetCurrentContext();  
    CGContextBeginPath(context);  
    CGContextSetLineWidth(context, 2.0);  
    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);  
    CGFloat lengths[] = {10,10};  
    CGContextSetLineDash(context, 0, lengths,2);  
    CGContextMoveToPoint(context, 10.0, 20.0);  
    CGContextAddLineToPoint(context, 310.0,20.0);  
    CGContextStrokePath(context);  
    CGContextClosePath(context);  
    

    十七、自动布局中多行UILabel,需要设置其preferredMaxLayoutWidth属性才能正常显示多行内容。另外如果出现显示不全文本,可以在计算的结果基础上+0.5。

        CGFloat h = [model.message boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - kGAP-kAvatar_Size - 2*kGAP, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size.height+0.5;
    

    十八、 禁止程序运行时自动锁屏
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];

    十九、KVC相关,支持操作符
    KVC同时还提供了很复杂的函数,主要有下面这些
    ①简单集合运算符
    简单集合运算符共有@avg, @count , @max , @min ,@sum5种,都表示啥不用我说了吧, 目前还不支持自定义。

    @interface Book : NSObject
    @property (nonatomic,copy)  NSString* name;
    @property (nonatomic,assign)  CGFloat price;
    @end
    @implementation Book
    @end
    
    
    Book *book1 = [Book new];
    book1.name = @"The Great Gastby";
    book1.price = 22;
    Book *book2 = [Book new];
    book2.name = @"Time History";
    book2.price = 12;
    Book *book3 = [Book new];
    book3.name = @"Wrong Hole";
    book3.price = 111;
    
    Book *book4 = [Book new];
    book4.name = @"Wrong Hole";
    book4.price = 111;
    
    NSArray* arrBooks = @[book1,book2,book3,book4];
    NSNumber* sum = [arrBooks valueForKeyPath:@"@sum.price"];
    NSLog(@"sum:%f",sum.floatValue);
    NSNumber* avg = [arrBooks valueForKeyPath:@"@avg.price"];
    NSLog(@"avg:%f",avg.floatValue);
    NSNumber* count = [arrBooks valueForKeyPath:@"@count"];
    NSLog(@"count:%f",count.floatValue);
    NSNumber* min = [arrBooks valueForKeyPath:@"@min.price"];
    NSLog(@"min:%f",min.floatValue);
    NSNumber* max = [arrBooks valueForKeyPath:@"@max.price"];
    NSLog(@"max:%f",max.floatValue);
    
    打印结果
    2016-04-20 16:45:54.696 KVCDemo[1484:127089] sum:256.000000
    2016-04-20 16:45:54.697 KVCDemo[1484:127089] avg:64.000000
    2016-04-20 16:45:54.697 KVCDemo[1484:127089] count:4.000000
    2016-04-20 16:45:54.697 KVCDemo[1484:127089] min:12.000000
    

    NSArray 快速求总和 最大值 最小值 和 平均值

    NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
    CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
    CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
    CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
    CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
    NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min);
    

    二十、使用MBProgressHud时,尽量不要加到UIWindow上,加self.view上即可。如果加UIWindow上在iPad上,旋转屏幕的时候MBProgressHud不会旋转。之前有人遇到这个bug,我让他改放到self.view上即可解决此bug。

    二十一、强制让App直接退出(非闪退,非崩溃)

        - (void)exitApplication {
            AppDelegate *app = [UIApplication sharedApplication].delegate;
            UIWindow *window = app.window;
            [UIView animateWithDuration:1.0f animations:^{
                window.alpha = 0;
            } completion:^(BOOL finished) {
                exit(0);
            }];
        }
    

    二十二、Label行间距

     NSMutableAttributedString *attributedString =    
       [[NSMutableAttributedString alloc] initWithString:self.contentLabel.text];
        NSMutableParagraphStyle *paragraphStyle =  [[NSMutableParagraphStyle alloc] init];  
       [paragraphStyle setLineSpacing:3];
    
        //调整行间距       
       [attributedString addAttribute:NSParagraphStyleAttributeName 
                             value:paragraphStyle 
                             range:NSMakeRange(0, [self.contentLabel.text length])];
         self.contentLabel.attributedText = attributedString;
    

    二十三、CocoaPods pod install/pod update更新慢的问题
    pod install –verbose –no-repo-update
    pod update –verbose –no-repo-update
    如果不加后面的参数,默认会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少。

    二十四、MRC和ARC混编设置方式
    在XCode中targets的build phases选项下Compile Sources下选择 不需要arc编译的文件
    双击输入 -fno-objc-arc 即可
    MRC工程中也可以使用ARC的类,方法如下:
    在XCode中targets的build phases选项下Compile Sources下选择要使用arc编译的文件
    双击输入 -fobjc-arc 即可

    二十五、把tableview里cell的小对勾的颜色改成别的颜色
    _yourTableView.tintColor = [UIColor redColor];

    二十六、解决同时按两个按钮进两个view的问题
    [button setExclusiveTouch:YES];

    二十七、修改textFieldplaceholder字体颜色和大小

    textField.placeholder = @"请输入用户名";  
    [textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];  
    [textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
    

    二十八、禁止textField和textView的复制粘贴菜单
    这里有一个误区,很多同学直接使用UITextField,然后在VC里面写这个方法,返回NO,没效果。怎么搞都不行,但是如果用UIPasteboard的话,项目中所有的编辑框都不能复制黏贴了,真操蛋。
    我们要做的是新建一个类MyTextField继承UITextField,然后在MyTextField的.m文件里重写这个方法,就可以单独控制某个输入框了。

    -(BOOL)canPerformAction:(SEL)action withSender:(id)sender
    {
         if ([UIMenuController sharedMenuController]) {
           [UIMenuController sharedMenuController].menuVisible = NO;
         }
         return NO;
    }
    

    二十九:如何进入我的软件在app store 的页面
    先用iTunes Link 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

    三十、二级三级页面隐藏系统tabbar
    1、单个处理

    YourViewController *yourVC = [YourViewController new];
    yourVC.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:yourVC animated:YES];
    

    2.统一在基类里面处理
    新建一个类BaseNavigationController继承UINavigationController,然后重写 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated这个方法。所有的push事件都走此方法。

    @interface BaseNavigationController : UINavigationController
    
    @end
        -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
            if (self.viewControllers.count>0) {
        viewController.hidesBottomBarWhenPushed = YES;
        }
            [super pushViewController:viewController animated:animated];
        }
    

    三十一、取消系统的返回手势

       self.navigationController.interactivePopGestureRecognizer.enabled = NO;
    

    三十二、修改UIWebView中字体的大小,颜色

    1、UIWebView设置字体大小,颜色,字体:
    UIWebView无法通过自身的属性设置字体的一些属性,只能通过html代码进行设置
    在webView加载完毕后,在

    - (void)webViewDidFinishLoad:(UIWebView *)webView方法中加入js代码  
        NSString *str = @"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '60%'";  
        [_webView stringByEvaluatingJavaScriptFromString:str]; 
    

    或者加入以下代码

    NSString *jsString = [[NSString alloc] initWithFormat:@"document.body.style.fontSize=%f;document.body.style.color=%@",fontSize,fontColor];   
            [webView stringByEvaluatingJavaScriptFromString:jsString];   
    

    三十三、NSString处理技巧
    使用场景举例:可以用在处理用户用户输入在UITextField的文本

    //待处理的字符串
    NSString *string = @" A B  CD   EFG\n MN\n";
    
    //字符串替换,处理后的string1 = @"ABCDEF\nMN\n";
    NSString *string1 = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    //去除两端空格(注意是两端),处理后的string2 = @"A B  CD   EFG\n MN\n";
    NSString *string2 = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    
    //去除两端回车(注意是两端),处理后的string3 = @" A B  CD   EFG\n MN";
    NSString *string3 = [string stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    
    //去除两端空格和回车(注意是两端),处理后的string4 = @"A B  CD   EFG\n MN";
    NSString *string4 = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    

    三十四、主线程操作UI(对UI进行更新只能在主线程进行)
    解释:所谓的在主线程更新UI、操作UI,大致的意思就是设置UILabel的text或者设置tabbar的badgeValue,设置UIImageView的image等等。

    回到主线程方式1:

    [self performSelectorOnMainThread:@selector(updateImage:) withObject:data waitUntilDone:YES];
    

    performSelectorOnMainThread方法是NSObject的分类方法,每个NSObject对象都有此方法,
    它调用的selector方法是当前调用控件的方法,例如使用UIImageView调用的时候selector就是UIImageView的方法
    Object:代表调用方法的参数,不过只能传递一个参数(如果有多个参数请使用对象进行封装)
    waitUntilDone:是否线程任务完成执行

    回到主线程方式2:

    dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI的代码
        });
    

    这个不多解释,GCD的方法,注意不要在主线程掉用。

    三十五、判断模拟器

    if (TARGET_IPHONE_SIMULATOR) {
            NSLog(@"是模拟器");
        }else{
            NSLog(@"不是模拟器");
        }
    

    三十六、真机测试报 TCWeiboSDK 93 duplicate symbols for architecture armv7

    这是因为在项目中引用的两个相同的类库引起了,在我的项目中是因为引入的两个不同指令集引起的;

    三十七、AFnetWorking报”Request failed: unacceptable content-type: text/html”错误

    AFURLResponseSerialization.m文件设置

    self.acceptableContentTypes = [NSSetsetWithObjects:@"application/json", @"text/html",@"text/json",@"text/javascript", nil];
    

    加上@”text/html”,部分,其实就是添加一种服务器返回的数据格式。

    三十八、隐藏navigation跳转后的返回按钮

    //隐藏头部左边的返回
    self.navigationItem.hidesBackButton=YES;
    

    三十九、两种方法删除NSUserDefaults所有记录

    //方法一
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
    
    //方法二
    - (void)resetDefaults {
        NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
        NSDictionary * dict = [defs dictionaryRepresentation];
        for (id key in dict) {
            [defs removeObjectForKey:key];
        }
        [defs synchronize];
    }
    

    四十、UITableView设置Section间距
    在使用UITableViewStyleGrouped类型的UITableView的时候,经常很奇怪的出现多余的section间距,那可能是因为你只设置了footer或者header的间距中的其中一个,那么另一个默认为20个高度,只需要设置返回0.001的CGFlot的浮点数就可以解决这个多余的间距。

    //Header底部间距
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section  
    {  
        return 40;//section头部高度  
    }  
    
    //footer底部间距  
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section  
    {  
        return 0.001;  
    }  
    

    四十一、NSLog 输出格式集合

    • %@     对象
    • %d, %i    整数
    • %u      无符整形
    • %f       浮点/双字
    • %x, %X   二进制整数
    • %o      八进制整数
    • %zu     size_t
    • %p      指针
    • %e      浮点/双字 (科学计算)
    • %g      浮点/双字
    • %s       C 字符串
    • %.*s      Pascal字符串
    • %c       字符
    • %C       unichar
    • %lld      64位长整数(long long)
    • %llu      无符64位长整数
    %Lf       64位双字
    

    四十二、常用GCD总结

    为了方便地使用GCD,苹果提供了一些方法方便我们将block放在主线程 或 后台线程执行,或者延后执行。使用的例子如下:

        //  后台执行: 
         dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
              // something 
         }); 
         // 主线程执行: 
         dispatch_async(dispatch_get_main_queue(), ^{ 
              // something 
         }); 
         // 一次性执行: 
         static dispatch_once_t onceToken; 
         dispatch_once(&onceToken, ^{ 
             // code to be executed once 
         }); 
         // 延迟2秒执行: 
         double delayInSeconds = 2.0; 
         dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
         dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
             // code to be executed on the main queue after delay 
         }); 
    

    dispatch_queue_t 也可以自己定义,如要要自定义queue,可以用dispatch_queue_create方法,示例如下:

        dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL); 
        dispatch_async(urls_queue, ^{ 
             // your code 
        }); 
        dispatch_release(urls_queue); 
    

    另外,GCD还有一些高级用法,例如让后台2个线程并行执行,然后等2个线程都结束后,再汇总执行结果。这个可以用dispatch_group, dispatch_group_async 和 dispatch_group_notify来实现,示例如下:

        dispatch_group_t group = dispatch_group_create(); 
        dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 
              // 并行执行的线程一 
         }); 
         dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 
              // 并行执行的线程二 
         }); 
         dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ 
              // 上面的线程走完成后,最后通知走次block,保证这部分代码最后执行 
         }); 
    

    四十三、 iOS中的随机数

    生成0-x之间的随机正整数

    int value =arc4random_uniform(x + 1);
    

    生成随机正整数

    int value = arc4random() 
    

    通过arc4random() 获取0到x-1之间的整数的代码如下:

    int value = arc4random() % x; 
    

    获取1到x之间的整数的代码如下:

    int value = (arc4random() % x) + 1; 
    

    最后如果想生成一个浮点数,可以在项目中定义如下宏:

    #define ARC4RANDOM_MAX      0x100000000 
    

    然后就可以使用arc4random() 来获取0到100之间浮点数了(精度是rand()的两倍),代码如下:

    double val = floorf(((double)arc4random() / ARC4RANDOM_MAX) * 100.0f);
    

    四十四、系统自带的UITableViewCell,其中cell.accessoryView可以自定义控件

     if (indexPath.section == 2 && indexPath.row == 0) {
            cell.accessoryView = [[UISwitch alloc] init];
        } else {
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
    

    四十五、isKindOfClass, isMemberOfClass的用法区分

    -(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例
    -(BOOL) isMemberOfClass: classObj 判断是否是这个类的实例

    实例一:

       Person *person = [[Person alloc] init];      //父类
       Teacher *teacher = [[Teacher alloc] init];  //子类
    
       //YES   
       if ([teacher isMemberOfClass:[Teacher class]]) {  
            NSLog(@"teacher Teacher类的成员");  
       }  
       //NO   
       if ([teacher isMemberOfClass:[Person class]]) {  
           NSLog(@"teacher Person类的成员");  
       }  
       //NO   
       if ([teacher isMemberOfClass:[NSObject class]]) {  
           NSLog(@"teacher NSObject类的成员");  
       }  
    

    实例二:

    Person *person = [[Person alloc] init];  
    Teacher *teacher = [[Teacher alloc] init];  
    
    //YES   
    if ([teacher isKindOfClass:[Teacher class]]) {  
        NSLog(@"teacher 是 Teacher类或Teacher的子类");  
    }  
    //YES   
    if ([teacher isKindOfClass:[Person class]]) {  
        NSLog(@"teacher 是 Person类或Person的子类");  
    }  
    //YES   
    if ([teacher isKindOfClass:[NSObject class]]) {  
        NSLog(@"teacher 是 NSObject类或NSObject的子类");  
    }  
    

    isMemberOfClass判断是否是属于这类的实例,是否跟父类有关系他不管,所以isMemberOfClass指到父类时才会为NO;

    四十六、关于UIScreen

    UIScreen对象包含了整个屏幕的边界矩形。当构造应用的用户界面接口时,你应该使用该对象的属性来获得推荐的矩形大小,用以构造你的程序窗口。

    CGRect bound = [[UIScreen mainScreen] bounds]; // 返回的是带有状态栏的Rect
    CGRect frame = [[UIScreen mainScreen] applicationFrame]; // 返回的是不带有状态栏的Rect
    float scale = [[UIScreen mainScreen] scale]; // 得到设备的自然分辨率

    对于scale属性需要做进一步的说明:

    以前的iphone 设备屏幕分辨率都是320*480,后来apple 在iPhone 4中采用了名为Retina的显示技术,iPhone 4采用了960x640像素分辨率的显示屏幕。由于屏幕大小没有变,还是3.5英寸,分辨率的提升将iPhone 4的显示分辨率提升至iPhone 3GS的四倍,每英寸的面积里有326个像素。

    scale属性的值有两个:
    scale = 1; 的时候是代表当前设备是320*480的分辨率(就是iphone4之前的设备)
    scale = 2; 的时候是代表分辨率为640*960的分辨率

    // 判断屏幕类型,普通还是视网膜  
        float scale = [[UIScreen mainScreen] scale];  
        if (scale == 1) {  
            bIsRetina = NO;  
            NSLog(@"普通屏幕");  
        }else if (scale == 2) {  
            bIsRetina = YES;  
            NSLog(@"视网膜屏幕");  
        }else{  
            NSLog(@"unknow screen mode !");  
        } 
    

    四十七、UIView的clipsTobounds属性

    view2添加view1到中,如果view2大于view1,或者view2的坐标不全在view1的范围内,view2是盖着view1的,意思就是超出的部份也会画出来,UIView有一个属性,clipsTobounds 默认情况下是NO。如果,我们想要view2把超出的那部份现实出来,就得改变它的父视图也就view1的clipsTobounds属性值。view1.clipsTobounds = YES;
    可以很好地解决覆盖的问题

    四十八、百度坐标跟火星坐标相互转换

    //百度转火星坐标
    + (CLLocationCoordinate2D )bdToGGEncrypt:(CLLocationCoordinate2D)coord
    {
        double x = coord.longitude - 0.0065, y = coord.latitude - 0.006;
        double z = sqrt(x * x + y * y) - 0.00002 * sin(y * M_PI);
        double theta = atan2(y, x) - 0.000003 * cos(x * M_PI);
        CLLocationCoordinate2D transformLocation ;
        transformLocation.longitude = z * cos(theta);
        transformLocation.latitude = z * sin(theta);
        return transformLocation;
    }
    
    //火星坐标转百度坐标
    + (CLLocationCoordinate2D )ggToBDEncrypt:(CLLocationCoordinate2D)coord
    {
        double x = coord.longitude, y = coord.latitude;
    
        double z = sqrt(x * x + y * y) + 0.00002 * sin(y * M_PI);
        double theta = atan2(y, x) + 0.000003 * cos(x * M_PI);
    
        CLLocationCoordinate2D transformLocation ;
        transformLocation.longitude = z * cos(theta) + 0.0065;
        transformLocation.latitude = z * sin(theta) + 0.006;
    
        return transformLocation;
    }
    

    四十九、绘制1像素的线

    #define SINGLE_LINE_WIDTH           (1 / [UIScreen mainScreen].scale)
    #define SINGLE_LINE_ADJUST_OFFSET   ((1 / [UIScreen mainScreen].scale) / 2)
    

    代码如下:

    UIView *view = [[UIView alloc] initWithFrame:CGrect(x - SINGLE_LINE_ADJUST_OFFSET, 0, SINGLE_LINE_WIDTH, 100)];
    

    注意:如果线宽为偶数Point的话,则不要去设置偏移,否则线条也会失真

    五十、UILabel显示HTML文本(IOS7以上)

    NSString * htmlString = @"<html><body> Some html string \n <font size=\"13\" color=\"red\">This is some text!</font> </body></html>";
        NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
        UILabel * myLabel = [[UILabel alloc] initWithFrame:self.view.bounds];
        myLabel.attributedText = attrStr;
        [self.view addSubview:myLabel];
    

    五十一、添加pch文件的步聚

    1:创建新文件 ios->other->PCH file,创建一个pch文件:“工程名-Prefix.pch”:
    2:将building setting中的precompile header选项的路径添加“$(SRCROOT)/项目名称/pch文件名”(例如:$(SRCROOT)/LotteryFive/LotteryFive-Prefix.pch)
    3:将Precompile Prefix Header为YES,预编译后的pch文件会被缓存起来,可以提高编译速度
    

    五十二、兼容字体大小6plue跟它以下的区别

    #define FONT_COMPATIBLE_SCREEN_OFFSET(_fontSize_)  [UIFont systemFontOfSize:(_fontSize_ *([UIScreen mainScreen].scale) / 2)]
    在iPhone4~6中,缩放因子scale=2;在iPhone6+中,缩放因子scale=3
    
    运用时:
    
    myLabel.font=FONT_COMPATIBLE_SCREEN_OFFSET(15);
    

    五十三、APP虚拟器可以运行,在真机调试时报这个问题,因为把项目名称设成中文导致

    App installation failed
    There was an internal API error.
    Build Settings中的Packaging的Product Name设置成中文

    五十四、关于Masonry

    a:make.equalTo 或 make.greaterThanOrEqualTo (至多) 或 make.lessThanOrEqualTo(至少)
    
    make.left.greaterThanOrEqualTo(label);
    make.left.greaterThanOrEqualTo(label.mas_left);
    
    //width >= 200 && width <= 400
    make.width.greaterThanOrEqualTo(@200);
    make.width.lessThanOrEqualTo(@400)
    b:masequalTo 和 equalTo 区别:masequalTo 比equalTo多了类型转换操作,一般来说,大多数时候两个方法都是 通用的,但是对于数值元素使用mas_equalTo。对于对象或是多个属性的处理,使用equalTo。特别是多个属性时,必须使用equalTo
    
    c:一些简便赋值
    
    // make top = superview.top + 5, left = superview.left + 10,
    // bottom = superview.bottom - 15, right = superview.right - 20
    make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))
    
    // make width and height greater than or equal to titleLabel
    make.size.greaterThanOrEqualTo(titleLabel)
    
    // make width = superview.width + 100, height = superview.height - 50
    make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50))
    
    // make centerX = superview.centerX - 5, centerY = superview.centerY + 10
    make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10))
    
    d:and关键字运用
    
    make.left.right.and.bottom.equalTo(superview); 
    make.top.equalTo(otherView);
    e:优先;优先权(.priority,.priorityHigh,.priorityMedium,.priorityLow)
    
    .priority允许您指定一个确切的优先级
    .priorityHigh 等价于UILayoutPriorityDefaultHigh
    .priorityMedium 介于高跟低之间
    .priorityLow 等价于UILayoutPriorityDefaultLow
    
    实例:
    make.left.greaterThanOrEqualTo(label.mas_left).with.priorityLow();
    make.top.equalTo(label.mas_top).with.priority(600);
    g:使用mas_makeConstraints创建constraint后,你可以使用局部变量或属性来保存以便下次引用它;如果创建多个constraints,你可以采用数组来保存它们
    
    // 局部或者全局
    @property (nonatomic, strong) MASConstraint *topConstraint;
    
    // 创建约束并赋值
    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        self.topConstraint = make.top.equalTo(superview.mas_top).with.offset(padding.top);
        make.left.equalTo(superview.mas_left).with.offset(padding.left);
    }];
    
    // 过后可以直接访问self.topConstraint
    [self.topConstraint uninstall];
    
    h:mas_updateConstraints更新约束,有时你需要更新constraint(例如,动画和调试)而不是创建固定constraint,可以使用mas_updateConstraints方法
    
    
    - (void)updateConstraints {
        [self.growingButton mas_updateConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self);
            make.width.equalTo(@(self.buttonSize.width)).priorityLow();
            make.height.equalTo(@(self.buttonSize.height)).priorityLow();
            make.width.lessThanOrEqualTo(self);
            make.height.lessThanOrEqualTo(self);
        }];
    
        //调用父updateConstraints
        [super updateConstraints];
    }
    
    i:mas_remakeConstraints更新约束,mas_remakeConstraints与mas_updateConstraints比较相似,都是更新constraint。不过,mas_remakeConstraints是删除之前constraint,然后再添加新的constraint(适用于移动动画);而mas_updateConstraints只是更新constraint的值。
    
    
    - (void)changeButtonPosition {
        [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.size.equalTo(self.buttonSize);
    
            if (topLeft) {
           make.top.and.left.offset(10);
            } else {
           make.bottom.and.right.offset(-10);
            }
        }];
    }
    

    五十五、iOS中的round/roundf/ceil/ceilf/floor/floorf

    round:如果参数是小数,则求本身的四舍五入。
    ceil:如果参数是小数,则求最小的整数但不小于本身(向上取,ceil的英文意思有天花板的意思)
    floor:如果参数是小数,则求最大的整数但不大于本身(向下取,floor的英文意思有地板的意思)

    Example:如果值是3.4的话,则
    3.4 – round 3.000000
    – ceil 4.000000
    – floor 3.00000

    五十六、中文输入法的键盘上有联想、推荐的功能,所以可能导致文本内容长度上有些不符合预期,导致越界

    * Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds’
    处理方式如下(textView.markedTextRange == nil)

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        if (textView.text.length >= self.textLengthLimit && text.length > range.length) {
            return NO;
        }
    
        return YES;
    }
    
    - (void)textViewDidChange:(UITextView *)textView
    {
        self.placeholder.hidden = (self.textView.text.length > 0);
    
        if (textView.markedTextRange == nil && self.textLengthLimit > 0 && self.text.length > self.textLengthLimit) {
            textView.text = [textView.text substringToIndex:self.textLengthLimit];
        }
    }
    

    五十七、关于导航栏透明度的设置及顶部布局起点位置设置

    属性:translucent

    关闭

    self.navigationController.navigationBar.translucent = NO;

    开启

    self.navigationController.navigationBar.translucent = YES;

    属性:automaticallyAdjustsScrollViewInsets

    当 automaticallyAdjustsScrollViewInsets 为 NO 时,tableview 是从屏幕的最上边开始,也就是被 导航栏 & 状态栏覆盖

    当 automaticallyAdjustsScrollViewInsets 为 YES 时,也是默认行为

    五十八、UIScrollView偏移64问题

    在一个VC里如果第一个控件是UIScrollView,注意是第一个控件,就是首先addsubview在VC.view上。接着加到scrollView上的View就会在Y点上发生64的偏移(也就是navigationBar的高度44+电池条的高度20)。
    这个在iOS7以后才会出现。

    解决办法:
    self.automaticallyAdjustsScrollViewInsets = false; self是你当前那个VC。

    如果这个scrollView不是第一个加到self.view上的。也不会发生64的偏移。

    五十九、UIWebView在IOS9下底部出现黑边解决方式

    UIWebView底部的黑条很难看(在IOS8下不会,在IOS9会出现),特别是在底部还有透明控件的时候,隐藏的做法其实很简单,只需要将opaque设为NO,背景色设为clearColor即可

    六十、tabBarController跳转到另一个一级页面

    当我们用tabBarController时,若已经到其中一个TabBar的子页,又要跳转到某一个一级的页面时,如果这样写,导致底部出现黑边,引起tabbar消失的bug

    [self.navigationController popToRootViewControllerAnimated:YES];
    
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
    

    解决方法一:删除动画

     [self.navigationController popToRootViewControllerAnimated:NO];
    
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
    

    解决方法二:延迟执行另一个系统操作

     [self.navigationController popToRootViewControllerAnimated:NO];
    
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
    
        });
    

    六十一、UIWebView获取Html的标题title

    titleLabel.text = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    

    六十二、汉字转为拼音

    - (NSString *)Charactor:(NSString *)aString getFirstCharactor:(BOOL)isGetFirst
    {
        //转成了可变字符串
        NSMutableString *str = [NSMutableString stringWithString:aString];
        //先转换为带声调的拼音
        CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
        //再转换为不带声调的拼音
        CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
        CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
        NSString *pinYin = [str capitalizedString];
        //转化为大写拼音
        if(isGetFirst)
        {
            //获取并返回首字母
            return [pinYin substringToIndex:1];
        }
        else
        {
            return pinYin;
        }
    }
    

    六十三、属性名以new开头解决方式
    因为new为OC关键词,类似的还有alloc
    @property (nonatomic,copy) NSString *new_Passwd;

    像上面这样写法会报错,可以替换成

    @property (nonatomic,copy,getter = theNewPasswd) NSString *new_Passwd;

    六十四、去除编译器警告

    a:方法弃用告警

    #pragma clang diagnostic push  
    
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"      
    //会报警告的方法,比如SEL 
    [TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];  
    
    #pragma clang diagnostic pop  
    

    b:未使用变量

    #pragma clang diagnostic push   
    #pragma clang diagnostic ignored "-Wunused-variable"   
    
    int a;   
    
    #pragma clang diagnostic pop 
    

    六十五、self.navigationController.viewControllers修改
    主要解决那些乱七八糟的跳转逻辑,不按顺序来的问题;

    var controllerArr = self.navigationController?.viewControllers//获取Controller数组
    controllerArr?.removeAll()//移除controllerArr中保存的历史路径
        //重新添加新的路径
    controllerArr?.append(self.navigationController?.viewControllers[0])
    controllerArr?.append(C)
    controllerArr?.append(B)
        //这时历史路径为(root -> c -> b)
        //将组建好的新的跳转路径 set进self.navigationController里
    self.navigationController?.setViewControllers(controllerArr!, animated: true)
    //直接写入,完成跳转B页面的同时修改了之前的跳转路径
    

    六十六、数组逆序遍历

    1、枚举法

    NSArray *array = @[@"1",@"2",@"3",@"5",@"6"];
        [array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"%@",obj);
        }];
    

    2、for循环

            NSArray*array=@[@"1",@"2",@"3",@"5",@"6"];
    
     for (NSInteger index = array.count-1; index>=0; index--) {
            NSLog(@"%@",array[index]);
        }
    

    六十七、获取iPhone手机上安装的所有应用程序的信息

    信息包括,bundle identitifer,name、版本号,私有API,上架会被拒

    Class c =NSClassFromString(@”LSApplicationWorkspace”);
    下面这句代码是卸载模拟器上的app的。
    [[c new] performSelector:@selector(uninstallApplication:withOptions:) withObject:@”come.ihk.RCIM” withObject:nil];

    id s = [(id)c performSelector:NSSelectorFromString(@"defaultWorkspace")];
    NSArray *array = [s performSelector:NSSelectorFromString(@"allInstalledApplications")];
    for (id item in array)
    {
        NSLog(@"%@",[item performSelector:NSSelectorFromString(@"applicationIdentifier")]);
        NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleIdentifier")]);
    

    // NSLog(@”%@”,[item performSelector:NSSelectorFromString(@”bundleVersion”)]);
    // NSLog(@”%@”,[item performSelector:NSSelectorFromString(@”shortVersionString”)]);
    NSLog(@”%@”,[item performSelector:NSSelectorFromString(@”itemName”)]);

    }
    

    六十八、获取一个类的所有子类,就是老王有几个儿子的问题
    比如获取AVAsset的所有子类

    int numClasses;
    Class *classes = NULL;
    numClasses = objc_getClassList(NULL,0);

    if (numClasses >0 )
    {
        classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses);
        numClasses = objc_getClassList(classes, numClasses);
        for (int i = 0; i < numClasses; i++) {
            if (class_getSuperclass(classes[i]) == [AVAsset class]){
                NSLog(@"%@", NSStringFromClass(classes[i]));
            }
        }  
        free(classes);  
    }
    

    结果:AVAsset的子类有AVAssetProxy、AVComposition、AVDataAsset、AVURLAsset。其中AVAssetProxy和AVDataAsset为系统私有API类,开发者可用的为AVComposition和AVURLAsset
    PS:AVComposition的一个子类为AVMutableComposition,算是AVAsset的孙子了。上述方法获得的是直接子类,也就是儿子,孙子获取不到。如果需要获取,那么继续调用上面的方法。

    六十九、上提加载更多闪屏+抖动的bug
    设置tableview的预估行高为零。
    self.tableView.estimatedRowHeight = 0;

    七十、如何让系统方法调用时报错,或者防止team中其他成员调用你的类中的某个方法。
    例如单例中的使用场景:
    - (instancetype)init NS_UNAVAILABLE;
    + (instancetype)new NS_UNAVAILABLE;

    这里写图片描述

    展开全文
  •  利用Xcode 打包时 勾选 了 "Include app symbols for your application to receive symbolicated crash logs from Apple." 2. 解决方案  打包时去掉勾选,就不会生成 Symbols 文件夹。 转载于:...

    1. 原因  

      利用Xcode 打包时 勾选 了 "Include app symbols for your application to receive symbolicated crash logs from Apple."

    2. 解决方案 

      打包时去掉勾选,就不会生成 Symbols 文件夹。

    转载于:https://www.cnblogs.com/pinweyshg/p/9154042.html

    展开全文
  • Symbols tool failed

    2018-11-30 16:19:02
    Symbols tool failed 错误: 解决方法:

    Symbols tool failed

    错误:

    在这里插入图片描述

    解决方法:

    在这里插入图片描述

    展开全文
  • unity设置iOS手机震动

    2020-03-01 12:39:40
    玩很多游戏的时候,线性马达的触感很棒,...iOS 提供了另外一个接口 AudioServicesPlaySystemSound(1519); 需要用uinty调用IOS接口: 在unity iOS工程里创建oc混编文件,ShortVibrator.mm文件里代码如下 #impo...
  • 我们iOS项目打包后生成的.app文件到底长什么样呢?我们来看一下: 首先在打包好的文件夹下找到.app文件,然后解压: 上图是解压后的文件目录:Symbols文件夹下有一个.symbols的符号表文件,文件作用暂不清楚,...
  • iOS开发中经常遇到的一个错误是Undefined symbols for architecture arm64,这个错误表示工程某些地方不支持arm64指令集。那我们应该怎么解决这个问题了?我们不仅要解决这个问题,更要了解出现这个问题的根源.这样...
  • iOS库 .a与.framework区别

    2017-11-27 15:26:17
    一、什么是库? 库是共享程序代码的方式,一般分为静态库和动态库。 二、静态库与动态库的区别?...静态库:链接时完整地拷贝至可执行文件中,...三、iOS里静态库形式? .a和.framework 四、iOS里动态库形式?
  • 现在的需求是合并IOS工程和unity3d工程需要。 目前的方案有两种: 1.把unity导出的ios工程嵌入IOS原生工程 2.把IOS工程嵌入unity导出的IOS原生工程 两种方式各有优劣,下面来分析下 1.unity导出工程包含几个类库,...
  • 当我在ios11版本下直接将文件拉进工程时报如下错误. Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_QQApiInterface", referenced from: objc-class-ref in AppDelegate.o 检查后发现原因为:直接...
  • 废话不多说,上步骤: ...首先下载iOS DeviceSupport Files https://github.com/LiynXu/LiynXu.github.io/blob/0292cf234f5561cad2ea2b5f183476c0fabe0302/2019/11/01/iOS--DeviceSupport_updated_13.2.2_17B102...
  • 在开发期间集成ZBar 和 支付 的时候,发现很多提示是.o文件冲突,最常见的时base64冲突,原因是由于不少第三方静态库中都有base64这个文件 在网上查了许久,发现都是转载的同一篇文章,由于对console命令不熟悉,也...
  • 联系人:石虎 QQ:1224614774 昵称: ... QQ群:807236138 群称: iOS 技术交流学习群 一、报错详情   Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_Person", referenced from: _OB...
  • 一,Xcode编译出现Link错误,出现"duplicate symbols for architecture i386 clang"提示. 问题:链接时,项目有重名文件. 解决: 根据错误提示,做如下检查: 1.Taraget->Build Settings->Link Binary With Libraries...
  • 1.模拟器的目录: 点击“Finder->前往->资源库->Developer->Xcode->DerivedData”,【看不到“资源库”?点击“前往”,看到菜单栏时,按“Option”就看到了.】或者点击“Finder->前往->前往文件夹”,输入:”/...
  • 使用cocoapod加入第三方库,打开项目有时会出现...Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_AFHTTPRequestOperationManager", referenced from: objc-class-ref in AFNetworkingUtil.o ld: symb
  • 源博客:http://www.cocoachina.com/ios/20170221/18737.html首先声明因为我是在真机上编译的项目,所以报错的架构(CPU指令集)为arm64。...Undefined symbols for architecture x86_64:如果我们使用3
  • 摘要: iOS静态库 一、什么是库? 库是共享程序代码的方式。 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 iOS中的静态库有 .a 和 .framework两种形式...
  • iOS配置Other Linker Flags

    2018-12-29 09:45:33
    1.在引入第三方库的时候,运行程序崩溃,控制台显示 unrecognized selector sent to class ,很明显代码中调用不存在的...2.在Other Linker Flags中配置 -ObjC ,运行程序报错,显示 duplicate symbols for arch...
1 2 3 4 5 ... 20
收藏数 6,651
精华内容 2,660
关键字:

.symbols ios