iOS开发知识点

作者: 喵小帅 | 来源:发表于2016-04-18 11:29 被阅读2723次

    get请求和post请求

    提交用户的隐私数据一定要使用POST请求,相对于POST请求而言,GET请求的所有参数都直接暴露在URL中,请求的URL一般都会记录在服务器的访问日志中,而服务器的访问日志是黑客攻击的主要对象之一。
    这里所说的用户隐私数据一般来说是指登录密码,银行账号等等。

    URL不允许写中文怎么办

    可以通过转码的方式进行解决

    urlStr= [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    

    如何判断一个实例是否属于特定的子类型

    可以使用类型操作符(is)来进行判断,如果实例属于那个子类型,类型操作符返回true,反则的话返回false

    let str = "abcdef"
    if str is String 
    {
            print("string")
    }
    else
    {
            print("noString")
    }
    

    遍历所有的cell

    for(NSIndexPath *cellIndex in [self.tableView indexPathsForVisibleRows])
    TableViewCell *otherCell = [self.tableView cellForRowAtIndexPath:cellIndex];
    

    栈和堆的理解

    管理方式:
    对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
    申请大小:
    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
    碎片问题:
    对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
    分配方式:
    堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
    分配效率:
    栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

    简而言之,操作系统使用stack 段中的指针值访问heap 段中的对象。如果stack 对象的指针没有了,则heap 中的对象就不能访问。这也是内存泄露的原因。

    assign得到的b是栈和堆都跟a相同
    retain得到的b是在栈上重新开了一个地址,和a共同管理在堆上的内容
    copy得到的b是栈和堆都开辟新的地址。

    guard的使用

    //检查身份证,如果身份证没带,则不能进入考场
    guard let id = person["id"]else
    {
        print("没有身份证,不能进入考场")
        return
    }
    //身份证和准考证齐全,方可进入考场
          print("您的身份证号为:\(id),准考证号为:\(examNumber)。请进入考场!")
    

    这里值得注意的是,id和examNumber可以在guard语句之外使用,也就是说当guard对其表达式进行验证后,id和examNumber可在整个方法的作用域中使用,并且是解包后的。

    tableview左侧空白处理

    在ios7中,UITableViewCell左侧会有默认15像素的空白。这时候,设置setSeparatorInset:UIEdgeInsetsZero 能将空白去掉。
    但是在ios8中,设置setSeparatorInset:UIEdgeInsetsZero 已经不起作用了。下面是解决办法
    首先在viewDidLoad方法加入以下代码:

     if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
    [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
    [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
    

    然后在UITableView的代理方法中加入以下代码

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
    [cell setSeparatorInset:UIEdgeInsetsZero];
    }
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
    [cell setLayoutMargins:UIEdgeInsetsZero];
    }
    }
    

    UIView的clipsToBounds和CALayer的的masksToBounds之间的关系??

    clipsToBounds
    是指视图上的子视图,如果超出父视图的部分就截取掉,
    masksToBounds
    却是指视图的图层上的子图层,如果超出父图层的部分就截取掉

    图像的拉伸方法

    - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:
    

    关于GCD的一些常用方法

    // 创建目标队列
    let workingQueue = dispatch_queue_create("my_queue", nil)
    
    // 派发到刚创建的队列中,GCD 会负责进行线程调度
    dispatch_async(workingQueue) {
        // 在 workingQueue 中异步进行
        print("努力工作")
        NSThread.sleepForTimeInterval(2)  // 模拟两秒的执行时间
    
        dispatch_async(dispatch_get_main_queue()) {
            // 返回到主线程更新 UI
            print("结束工作,更新 UI")
        }
    }
    

    多线程单例

    dispatch_once_t必须是全局或static变量
    //静态变量,保证只有一份实例,才能确保只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
       //单例代码 
    });
    

    关于时间的一些宏

    #define NSEC_PER_SEC 1000000000ull
    #define USEC_PER_SEC 1000000ull
    #define NSEC_PER_USEC 1000ull
    
    NSEC:纳秒。
    USEC:微秒。
    SEC:秒
    PER:每
    
        1   NSEC_PER_SEC,每秒有多少纳秒。
        2   USEC_PER_SEC,每秒有多少毫秒。(注意是指在纳秒的基础上)
        3   NSEC_PER_USEC,每毫秒有多少纳秒。
    

    mac使用技巧

    在Mac下想知道某个目录下各个文件和子目录各占多少空间,不需要一个一个去查看。打开终端,在该目录下输入:du -sh *,结果是啥,你们试试就知道了

    很多刚开始使用Mac的用户,一般都知道Spotlight功能,快速定位和检索文件。事实上用这个功能还可以快速打开程序。通过ctrl+space呼出,输入通讯或cont,都可以找到通讯录这个程序,回车即可打开

    shift+command+3:全屏幕截图;shift+command+4:通过鼠标选取截图。

    1、Mac的原生输入法
    我在Mac下曾经使用过很多输入法,包括FIT、搜狗、QQ、QIM等,这是因为Mac的原生输入法太不给力了。但是OS X升级到Mountain Lion之后,原生输入法有了很大的改进,慢慢的,现在最常用的变成了原生输入法,今天就为大家介绍一些Mac输入法的操作技巧
    中英文混合输入,输入中文的时候,打开caps lock键,可以直接输入英文,关掉又切换回中文
    选词,通过-+号可以切换字或词,通过[]可以展开候选词列表并进行切换
    打开输入法偏好设置,可以设置自动校正模糊音
    用 ' 可以进行手动分词,比如fang'an(方案)
    适用shift + 6可以输入表情符号,比如(☆_☆)凸-

    2、Safari的标签
    当你想在新的标签页打开网页时,只需要按住command键,点击链接即可
    使用 Multi-Touch 手势在标签页中切换。在触控板上,双指开合即可显示你打开的标签页。在标签视图中,双指轻扫可浏览不同标签页
    通过shift+command+左右方向键,可以快速在Safari中打开的标签中进行切换。

    设置全局打印

    #ifdef DEBUG
    #define DMLog(...)NSLog(@"%s%@",__PRETTY_FUNCTION__,[NSString stringWithFormat:__VA_ARGS__])
    #else
    #define DMLog(...) do { } while (0)
    #endif
    

    让Xcode的控制台支持LLDB类型的打印

    1. touch ~/.lldbinit
    2. echo display @import UIKit >> ~/.lldbinit
    3. echo target stop-hook add -o "target stop-hook disable" >> ~/.lldbinit
      删除
      其实很简答, 看第一条命令touch ~/.lldbinit 就是在根目录下创建了一个隐藏文件.lldbinit , 然后删除这个文件就搞定啦. 打开终端然后, 在终端输入 :
      rm ~/.lldbinit 命令即可

    让程序在后台长久运行的示例代码:

    // AppDelegate.h 文件
    @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;
    
    // AppDelegate.m 文件
    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        [self beingBackgroundUpdateTask];
        // 在这里加上你需要长久运行的代码
        [self endBackgroundUpdateTask];
    }
    
    - (void)beingBackgroundUpdateTask
    {
        self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            [self endBackgroundUpdateTask];
        }];
    }
    
    - (void)endBackgroundUpdateTask
    {
        [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
        self.backgroundUpdateTask = UIBackgroundTaskInvalid;
    }
    

    相关文章

      网友评论

      • STDawn:比较基础的
      • liwb:for(NSIndexPath *cellIndex in [self.tableView indexPathsForVisibleRows])
        TableViewCell *otherCell = [self.tableView cellForRowAtIndexPath:cellIndex];
        这个只能遍历屏幕上可见的cell 的indexPath 要想获取所有的indexPath应该这样吧

        - (NSArray *)cellsForTableView:(UITableView *)tableView {
        NSInteger sections = tableView.numberOfSections;
        NSMutableArray *cells = [[NSMutableArray alloc] init];
        for (int section = 0; section < sections; section++) {
        NSInteger rows = [tableView numberOfRowsInSection:section];
        for (int row = 0; row < rows; row++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
        [cells addObject:indexPath];
        }
        }
        return cells;
        }
        在通过遍历存放 indexPath的数组 获取所有的Cell
        喵小帅:@李二超 我觉得你要实现这个功能的话,最好是利用给button加个tag值,设置唯一标识来让系统知道你具体哪个button进行了点击,这样就不会出现复用的情况的
        超_iOS:@喵小帅 请教两位,我要写一个点击cell(有N个)展开输入评价内容,点击另一个cell后展开内容清空,若是点击写过内容的cell上的button后还是展示原来的内容,我的思路是吧cell用户写的数据存字典1了,再把这字典存在tableview的字典2中,字典2的key就是点击的Row,点击cell后用row对应的value来初始化cell,,,,但是每次点击没写过的cell后还是有数据(貌似重用了),不知道我表达清楚没
        喵小帅:@liwb 对的,我写的那个方法的确是遍历当前屏幕可见的cell的indexpath,你的方法则是能够获得所有indexpath的方法 :smile:

      本文标题:iOS开发知识点

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