iOS —— 没注意过的细节

作者: 逍遥晨旭 | 来源:发表于2017-12-01 12:31 被阅读69次

    1、[NSMutableArray array] 和 [[NSMutableArray alloc]init] (包括字典等同类) 的使用方法的区别:

    alloc (内存分配)以及init(初始化) Objective-C 协议分为非正式协议和正式协议 。
    这两个方式都是建立一个空的Array

    [NSMutableArray array]不需要release,使用autoreleasepool机制。
    [[NSMutableArray alloc] init]需要自己手动release

    2、升级完Xcode8.0后,Command + option +/ 即可多行注释代码,无需引入框架,但只在方法前才起作用

    3、要说 GCD 绝对是 iOS 里面最容易使用异步的一个方式了:

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
    
        dispatch_async(dispatch_get_main_queue(), ^{
        
        });
    });
    

    4、自定义对象中添加如下方法来支持下标取值特性:

    - (id)objectAtIndexedSubscript:(NSUInteger)idx {
        return container[idx];
    }
    - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx {
        container[idx] = obj;
    }
    

    5、UIWebView的大小符合HTML的内容

        - (void)webViewDidFinishLoad:(UIWebView *)webView{
            CGSize size=webView.scrollView.contentSize;//iOS 5+
            webView.bounds=CGRectMake(0,0,size.width,size.height);
        }
    

    6、UIWebView 能通过“捏合”手势进行缩放

    webview=[[UIWebView alloc]init];
    webview.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    webview.scalesPageToFit=YES;
    webview.multipleTouchEnabled=YES;
    webview.userInteractionEnabled=YES;
    

    7、获取UUID,作为统计的标示

    NSUUID *uuid = [[UIDevice currentDevice] identifierForVendor];
    NSString *uuidStr = [NSString stringWithFormat:@"%@",uuid];
    

    8、友盟收集到的崩溃以及解决办法

    Application received signal SIGABRT
    (null)
    ((
      0   CoreFoundation                      0x0000000192eed1d0 <redacted> + 148
      1   libobjc.A.dylib                     0x000000019192455c objc_exception_throw + 56
      2   CoreFoundation                      0x0000000192eed100 <redacted> + 0
      3   绝对潮流                        0x100100dac 绝对潮流 + 1052076
      4   libsystem_platform.dylib            0x0000000191f7d338 _sigtramp + 36
      5   libsystem_pthread.dylib             0x0000000191f83450 pthread_kill + 112
      6   libsystem_c.dylib                   0x0000000191e2f400 abort + 140
      7   libsystem_malloc.dylib              0x0000000191effa5c <redacted> + 0
      8   libsystem_malloc.dylib              0x0000000191f01028 <redacted> + 648
      9   libsystem_malloc.dylib              0x0000000191ef3240 malloc_zone_realloc + 180
      10  libsqlite3.dylib                    0x0000000193428c34 sqlite3_value_text + 1224
      11  libsqlite3.dylib                    0x000000019346ff38 sqlite3_rekey + 1568
      12  libsqlite3.dylib                    0x0000000193485f78 sqlite3_rekey + 91744
      13  libsqlite3.dylib                    0x00000001933f6c74 sqlite3_exec + 88428
      14  libsqlite3.dylib                    0x00000001933e5888 sqlite3_exec + 17792
      15  libsqlite3.dylib                    0x00000001933e3608 sqlite3_exec + 8960
      16  libsqlite3.dylib                    0x00000001933e2838 sqlite3_exec + 5424
      17  libsqlite3.dylib                    0x00000001933e1e2c sqlite3_exec + 2852
      18  libsqlite3.dylib                    0x00000001933e1ae0 sqlite3_exec + 2008
      19  绝对潮流                        0x1000b8d38 绝对潮流 + 757048
      20  绝对潮流                        0x1000b9380 绝对潮流 + 758656
      21  绝对潮流                        0x1000a83a0 绝对潮流 + 689056
      22  绝对潮流                        0x1000a845c 绝对潮流 + 689244
      23  绝对潮流                        0x1000b3bd8 绝对潮流 + 736216
      24  绝对潮流                        0x100077efc 绝对潮流 + 491260
      25  绝对潮流                        0x1000ceae8 绝对潮流 + 846568
      26  绝对潮流                        0x10009f2e8 绝对潮流 + 652008
      27  libdispatch.dylib                   0x0000000191d761fc <redacted> + 24
      28  libdispatch.dylib                   0x0000000191d761bc <redacted> + 16
      29  libdispatch.dylib                   0x0000000191d7ab2c _dispatch_main_queue_callback_4CF + 428
      30  CoreFoundation                      0x0000000192e9a810 <redacted> + 12
      31  CoreFoundation                      0x0000000192e983fc <redacted> + 1660
      32  CoreFoundation                      0x0000000192dc62b8 CFRunLoopRunSpecific + 444
      33  GraphicsServices                    0x000000019487a198 GSEventRunModal + 180
      34  UIKit                               0x0000000198e0d7fc <redacted> + 684
      35  UIKit                               0x0000000198e08534 UIApplicationMain + 208
      36  绝对潮流                        0x1000bf304 绝对潮流 + 783108
      37  libdyld.dylib                       0x0000000191da95b8 <redacted> + 4
      )
     
     dSYM UUID: 1CD37DB6-2A53-3394-9771-169AA2EFB537
     CPU Type: arm64
     Slide Address: 0x0000000100000000
     Binary Image: 绝对潮流
     Base Address: 0x000000010000c000
    

    这类的崩溃信息通常难以重现, 没有任何的重现步骤,所以我们得找到发布该版本时的原始代码,可能会需要回朔到以前的SVN或者Git版本。
    然后找到当时上传代码时使用的DYSM文件,这文件通常在.xcarchive文件中。 右键该文件, 然后通过Terminal工具cd到

    cd /Users/us10/Library/Developer/Xcode/Archives/2017-01-12/绝对潮流\ 17-1-12\ 下午5.33.xcarchive/dSYMs/绝对潮流.app.dSYM/Contents/Resources/DWARF
    

    注意:

    1。对于成功生成archvie的项目, 在这个archive的包中, 是可以通过显示包内容, 看到DSYMs文件夹和一个products文件夹, 继续显示DSYMs文件夹下,可以看到一个xxx.app.DSYM文件,继续对它显示包内容,可以看到Contents/Resources/DWARF/xxxx文件, 这个文件是编译后的二进制文件,通过它可以进行反编译,从而找到二进制对应的源码位置。

    2。 在xcode中,archive成功后, 会在Organizer界面中的Archives下, 可以看到所有的archive文件, 右键Show in Finder可以找到这个文件。

    然后执行 atos -arch arm64 -o 绝对潮流 0x10009f2e8 就可以看到这处内存地址反编译回来的源码行。

    eg:
    atos -arch arm64 -o 绝对潮流 0x1000b3bd8
    +[CLSqliteDB addBrowsingHistory:] (in ) (CLSqliteDB.m:28)
    

    最近可参考这篇文章

    使用 xib 和 storyboard 的优缺点

    使用 xib 和 storyboard 的优点

    1、开发界面所见即所得,可以快速通过拖拽构造界面。
    2、你可以从 storyboard 中很方便地梳理出所有View Controller的界面间的调用关系。这一点对于新加入项目组的开发同事来说,比较友好。
    3、使用 Storyboard 可以使用Table View Controller的 Static Cell 功能。对于开发一些 Cell 不多,但每个 Cell 都不一样的列表类设置界面会比较方便。
    4、通过实现 – (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 方法,每个 View Controller 的跳转逻辑都聚集在一处,这方便我们统一管理界面跳转和传递数据。
    5、Storyboard 可以方便将一些常用功能模块化和复用。
    

    使用 xib 和 storyboard 的缺点

    1、xib 对版本管理是灾难。storyboard 实际上的多个 xib 的集合,所以更容易让多人编辑产生冲突。而虽然它们是 xml 格式,但是冲突解决起来还是不如代码那么容易。
    2、苹果对 xib, storyboard 的设计中带有当前电脑的操作系统版本和 Xcode 版本。所以如果两个协作的开发者电脑操作系统或 Xcode 有不一样的话,每次打开必定会修改这个文件。另外即使操作系统版本和 Xcode 版本一样,有些时候打开看也会造成一些自动的修改。
    3、storyboard 带来的 segue 的概念对于开发来说并不省事,特别是在需要传递参数的时候。如果是用程序内部 trigger 一个 segue,那么需要在另一个回调的地方设置 dest view controller 的参数信息。
    4、我们发现 xib 中设置的颜色值并不精确,RGB 在真机 / 模拟器上常常会有 10 多像素的偏差。
    5、xib 和 storyboard 对继承的支持并不友好。无法做界面的继承。
    6、xib 和 storyboard 对搜索支持并不友好,无法方便地在 Xcode 中查找关键词(但是可以通过写 bash 命令来查找)。
    7、storyboard 对组合支持得不太好,不允许在一个 xib 中附带多个子 view。
    8、xib 和 storyboard 不太方便做界面的模块化管理,比如我们想统一修改界面中所有按钮的字体样式,那么在 xib 和 storyboard 只能一个一个手工修改,而如果是代码编写的,则只需要改一个工厂方法的实现即可。
    9、对于复杂的 App,storyboard 的性能会比较差。
    

    xib 和 storyboard 与手写代码的选择

    对于复杂的、动态生成的界面,建议使用手工编写界面。
    对于需要统一风格的按钮或UI控件,建议使用手工用代码来构造。方便之后的修改和复用。
    对于需要有继承或组合关系的 UIView 类或 UIViewController 类,建议用代码手工编写界面。
    对于那些简单的、静态的、非核心功能界面,可以考虑使用 xib 或 storyboard 来完成。
    

    你如何去把一个view的所有subview清空?

    方法1:

    如果知道NSArray有makeObjectsPerformSelector这个方法的人,他们能够说出直接使用这个方法,然后在selector里面写removeFromSuperView的selector,就好了,而且很省事,一句话就搞定。

    方法2:

    如果知道NSArray有enumerator方法的人,他们会说出使用这种方法枚举每一个subview,在block里把removeFromSuperView调用起来,也差不多两三行的事儿。

    方法3:

    不知道NSArray有上面这些方法的人,他会说用for...in...的方法遍历,然后取到这每一个subview,让他们执行removeFromSuperView。可能要花费大概四五行。

    //设置导航栏背景颜色为透明的
    //    UIImage *image = [[UIImage alloc] init];
    //    [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
    //    self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
    

    10、UINavigationController设置为self.window的root视图, 然后将UIVIewController设置为UINavigtionController的根视图.在UIViewController中加入一个ScrollView,在ScrollView中加入一个view.

    此时发现. scrollView并没有自动下移64像素,而 ScrollView中的子视图VIew自动下移了64个像素.

    解决方法:
    self.automaticallyAdjustsScrollViewInsets = NO;

    11、打印输出:You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.

    解决方法:

    方法一:


    方法一.png

    第二种方法:
    info.plist文件配置:Required background modes->App downloads content in response to push notifications

    相关文章

      网友评论

        本文标题:iOS —— 没注意过的细节

        本文链接:https://www.haomeiwen.com/subject/otskbttx.html