zoukankan      html  css  js  c++  java
  • 面试题总结

    @property与@synthesize、@dynamic


    @property:声明和实现getter/setter方法,生成_成员变量

    @synthesize::合成属性的getter/setter 方法

    @dynamic:告诉编译器 不生成getter/setter方法 包括成员变量

    @property +@sythesize  //property:声明set/get方法  @sythesize 负责生成_成员变量,实现getter/setter方法。


    @interface categoryController ()
    @property (nonatomic )NSString *dynamicStr;
    @property (nonatomic )NSString *synthesizeStr;
    
    @end
    
    @implementation categoryController
    
    {
        NSString *asd;
    }
    
    @dynamic dynamicStr;                           //告诉编译器 禁止实现该属性的 getter,setter方法,同时成员变量也不会创建。
    @synthesize synthesizeStr = synthesizeStr;     //合成器语法 自动合成getter,setter方法,同时设置成员变量 synthesizeStr
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //dynamic
        self.testStr = @"123";
        NSLog(@"self.testStr==%@",self.testStr);
        
        //synthesize
        synthesizeStr = @"100";
        NSLog(@"self.synthesizeStr==%@",self.synthesizeStr);
        
        self.synthesizeStr = @"200";
        NSLog(@"synthesizeStr===%@",synthesizeStr);
    }
    
    - (void)setTestStr:(NSString *)testStr
    {
        asd = testStr;
    }
    - (NSString *)testStr
    {
        return asd;
    }
    
    @end
    
    //控制台打印
    2017-06-22 11:09:11.189 TestForMe[2021:522795] self.testStr==123
    2017-06-22 11:09:11.189 TestForMe[2021:522795] self.synthesizeStr==100
    2017-06-22 11:09:11.189 TestForMe[2021:522795] synthesizeStr===200

    二: 比较 NSString 中 copy strong区别

    @property (copy ,nonatomic)NSString *cStr;
    @property (strong ,nonatomic)NSString *sStr;
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self copyWithStrongMethod1];
        [self copyWithStrongMethod2];
    
     
    }
    
    #pragma MARK 测试 日常 copy 和strong 的区别
    - (void)copyWithStrongMethod1
    {
        NSMutableArray *books = [@[@"book1"] mutableCopy];
        Person *person = [[Person alloc] init];
        person.strBooks = books;     //strong属性
        person.copBooks = books;    //copy属性
        [books addObject:@"book2"];
        NSLog(@"bookArray1:%@",person.strBooks);
        NSLog(@"bookArray2:%@",person.copBooks);
    }
    
    //控制台打印
    2017-07-06 15:08:30.858 TestForMe[15547:8771374] bookArray1:(
        book1,
        book2
    )
    2017-07-06 15:08:30.859 TestForMe[15547:8771374] bookArray2:(
        book1
    )
    
    - (void)copyWithStrongMethod2
    {
        NSMutableString *str = @"abc".mutableCopy;
        
        self.cStr = str;
        self.sStr = str;
    //    str = @"asdsad".mutableCopy;不行
        [str appendString:@" 123"];
       
        NSLog(@"str1===%@ str2===%@", self.cStr, self.sStr); // str1:hello world str2:hello
    }
    
    //控制台打印
    2017-07-06 15:08:30.859 TestForMe[15547:8771374] str1===abc str2===abc 123

    备注:

    备注:
    使用strong,则person.bookArray1与可变数组books指向同一块内存区域,books内容改变,导致person.bookArray1的内容改变,因为两者是同一个东西;而使用copy,person.bookArray2在赋值之前,将books内容复制,创建一个新的内存区域,所以两者不是一回事,books的改变不会导致person.bookArray2的改变。
    说到底,其实就是不同的修饰符,对应不同的setter方法,
    1. strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。
    2. copy对应的setter方法,是将_property先release(_property release),然后拷贝参数内容(property copy),创建一块新的内存地址,最后_property = property。

    *实现原理总结

    *****关于kvo: 

    1 监听机制,基于nsobject 两个方法willChangeValueForKey 和didChangeValueForKey,实现的。

    2 当给一个属性添加观察者时候,运行时,会创建一个继承对象所属类的派生类,并且重写被观察属性的set方法,默认一个对象的isa指针会之前所属类,而这是isa会指向这个新的派生类,所以其实被观察的属性的赋值操作是在这个派生类 里实现的。

    3 的当被监听的属性发生改变前,调用willChange方法 记录旧的值,改变结束 调用DidChangeValue新的值,出发kvo监听方法。

    *****kvo应用场景

    1 推送消息 消息时 放数组里面 我们的birgeValue显示红点提示 需要兼监听数组改变 给提示

    2 视频 监听进度条

    3 做轮播图监听 scrollview 监听contentOffSet 

    *****深拷贝 浅拷贝

    1 最大的区别就是 有否创建新对象。深拷贝内容拷贝,浅拷贝指针拷贝(内存地址拷贝)

    2 深拷贝,修改一个对象不影响另一个对象。

    3 浅拷贝,修改一个对象影响另外一个对象

    大体上 copy mutable copy 策略是深拷贝

    retain  strong是浅拷贝

    *****SDWebImage细节

    1 sd_setImageWithURL

    2 SDWebImageManager  单例 downloadImageWithURL

     内部  SDImageCache类(nscache)以以url为key queryDiskCacheForKey方法 Memory Cache 以url为key去内存中查询缓存图片,如果没有  Disk Cache:去磁盘上找。

    如果磁盘找到,会将图片设置到memory cache中。

    3 如果缓存数据查询成功,则返回,不成功则请求网络self.imageDownloader down…

    4 如果下载成功 [self.imageCache storeImage]储存 completedBlock回调前端展示

    ps 磁盘缓存清除策略

    1 清理过期缓存

    2 清理写入时间早的图片

    @interface SDImageCache : NSObject

    @property (assign, nonatomic) NSInteger maxCacheAge;//最大缓存时间

    @property (assign, nonatomic) NSUInteger maxCacheSize;//最大缓存空间

    //设置最大缓存空间

    [SDImageCache sharedImageCache].maxCacheSize = 1024 * 1024 * 50;    // 50M

    SDWebImage Bug

    磁盘图片渲染之前,需要得到图片的原始像素数据,然后去做绘制操作,所以图片需要解压缩。

    *****公司刷新 流程

    size :取多少

    offset:从哪里取

    count:总数

    刷新:

    设定size 20条 10条,offset 为0 加到数组中

    加载:

    设定size20条 10条,第一次 获取数据数组长度 offset 从这取值 取size条,加到数组。

    判断更多 has 数据数组个数< count总数

    设置footer view 给个提示 没有更多

    ***** svpullrefresh 原理

    创建个scrollView的分类  分类添加属性刷新头部显示的view 高度60 添加头部刷新view为scrollview的观察者,监听contentOffSet的改变,刷新头部view 有几种状态,加载状态,初始状态,停止状态,拖拽状态,在观察者监听方法里面,根据几种状态切换执行layoutSubview的显示

    *****bug

    当下拉刷新比较少时候 会先调用下拉加载 在调用下拉刷新,由于头部view,后尾部view都是scrollview的观察者,所以当offset改变时候,观察者方法都会调用,然后判断的也都是拖拽,

    解决:尾部控件拖拽状态进入加载还不都,还要&&上scollview.cotentset>0

    uiscrollview的分类

    /**********************************************************************************/

    *****tableview 滑动 cell 崩溃 (会议人气榜)

    且仅仅4s崩溃,其他的不崩溃 而且会有内存明显的飙升 正常100左右飙升到800

    断点调试 崩溃在sdwebimage里面 沙盒取出的图片转码 转位图时候,正常我们设置图片imageview setimage 都是在主线程中设置的 这其就包括解压图片为位图(很耗cpu) 然后calyer在view上做渲染。sdwebimage做法是开子线程去去做这个位图的解压缩,然后缓存 供ui使用,去沙盒中去图片的时候不做任何处理,直接取,这次奔溃的原因就是后台返回的图片太大 3000*5000,方案有两个第一大图片不处理 不解码这样性能差点 但不崩溃

    第二种是 沙盒取出的图片 先等比压缩下。

    我的方案是综合下 沙盒取出图片先判断如果款大于屏幕宽度 等比压缩下,小的不压缩,然后再去转码

    *******多线程场景应用

    qq分享要求的图片1m以内,后台传的图片1.2m发布出去 回调不掉。

    方案:下载图片nsdata datawithurl 网速慢直接卡死 要开线程 图片存储沙盒,等比压缩图片

    xmpp 环境配置

    材料:openfire服务器 mysql数据库(默认装到控制面板)

    1 openfire mac版 基于java开发的 所以要求电脑有java运行环境 

    没有的话需要安装jdk 查看java运行环境 终端执行命令 运行java -version 

    2 mysql (服务端的数据库)使用是需要有账户密码默认装到控制面板)

      1》安装完 mysql 默认账户是root 密码为空

      2》终端命令配置命令行配置 开启mysql 并设置密码 

      3》创建的数据库默认四个文件 有个test文件 

      4》管理工具navcat 还有个海豚(mysqlworkbeech)的 登录输入连接名称(自定义)输入IP地址 端口号默认3306

           账户名称 root 密码(你配置过得)配置的数据库名称为你自定义的名称

    3 关联openfire 和数据库1 导入openfire数据表文件到mysel(创建字段包括用户等)

     1》openfire建立数据库文件openfire数据库编码选择utf-8的

     2》默认open fire数据库安装到/user/local/openfire/ 数据库脚本保存在/user/local/openfire/ /resources/database/中

    支持很多种数据库 保存mysql的数据库到桌面 导入到mysql中,这样mysql就添加好数据库字段了

    4 关联openfire 和数据库1  后台管理设置关联数据库mysql

     

    后台配置 选中驱动类型:mysql 指定mysql路径 输入mysql   用户名密码:root 密码:123456

    配置openfire 后台账户密码 admin 123456

    设置jid:

    ***** coast / 宏定义

    coast(常量):修饰变量之用 (可以修饰基本数据类型 int ,oc对象:nesting),标记变量只读…

    应用场景:1 修饰全局变量 2 修饰方法参数

    PS:NSString *coast str;//  当用在全局变量,防止外部引用extern 修改..

      -(void)setTest:(int coast)a { }  修饰方法参数,防止参数被修改,修改了,当然set方法你就外面白白设置了!~ 

    ps:什么叫做常量,10.@“SDSADD” 叫常量 nssting *a  a叫做变量....

    ***** static / extern  全局变量 局部变量牛逼闪闪 

    static:修饰变量(全局,局部)使用

    修饰局部变量:

    作用:延长局部变量生命周期 (类似给局部变量变为全局变量的意思!)

    ps:局部变量本身存储堆栈区,方法结束局部变量随之销毁;static修饰后将局部变量copy到静态区,修饰后变量在运行中在静态区给局部变量分配一次内存空间,且仅仅执行一次,程序运行期间变量一直存在不会销毁。

    ps:打点断 ,发现下次执行这里断点过到下面去了。

    修饰全局变量:

    主要是作用域的问题,static修饰后仅在本类中可以使用,无法extain引用,全局变量则可以外部引用。

    场景:int做自增运算

    extern:外部引用  UIKIT EXTERN(牛逼闪闪的宏定义 吼吼~~)

    一个类中声明(及时写在方法里面也无妨),另一个类extern 可以直接引用。

    ps:无需等到程序会否执行到该方法,程序启动即分配内存空间,所以无需加载到该方法。

    ps:个人理解,类似通过extern关键字从静态区 引出一个全局变量的意思,然后重新声明,使用。。。

    全局变量:变量存储在静态区,程序运行时分配一次内存空间,然后不会再去执行了。

    局部变量:存放在栈空间中,方法执行结束,变量销毁。

    ????为什么 类方法 要用static 修饰全局变量

    ***** 项目性能优化

    1 懒加载  场景:初始化UI控件 2NSDateFormatter(日期格式化)

    2 tableview优化 实现: 高度,数据 提前缓存,tableview只做赋值运算 减少subVies数量,rowHeight sectionHooterHeight 直接设定,少用代理

    3 常识注意

    ***** NSURLCache

    缓存原理 NSURLQequest 对应一个NSURLURLCacheResponse

    缓存NSURLCache *cache = [NSURLCache shareURLCache];//掌握全局缓存

    ***** Block常识 (一)

    方法常用声明:@property (copy) void(^MyBlock)(void); 如果超出当前作用域之后仍然继续使用block,那么最好使用copy关键字,拷贝到堆区,防止栈区变量销毁

    _weak typeof(self) weakSelf = self;

    因此,__block和__weak修饰符的区别其实是挺明显的: 

    1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 

    2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。 

    3.__block对象可以在block中被重新赋值,__weak不可以。 

    PS:__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。

    ***** Block和copy (二)

    为什么要用copy:出于作用域考虑,默认block 存放在栈中,函数调用,栈分配内存,函数结束释放内存,block 销毁。再次调用block 时候报错野指针错误。当前block 变量指向的被释放的内存地址。所以需要copy到堆中,包住block的命。

    “他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。”

    ***** Block  copy/strong (三)

    使用retain也可以,但是block的retain行为默认是用copy的行为实现的,

    因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。

    ***** Block  copy/strong 扩展

    block内部不引入外部变量:__ NSGlobalBlock

    block内部引入外部变量   :__ NSStackBlock

    ***** weak 实现原理

    runtime维护这个一个weak表(哈希表),记录已对象的地址为key,value为 所有指向该对象的weak弱指针地址的数组,当对象销毁时候通过weak表中该对象地址的value,查找到存有所有弱指针的地址的数组,赋值为nil,然后从weak表中删除。

    对象销毁 会调用objec_clear_deallocating函数

    assign weak 区别

    assign:修饰对象,和基本数据类型;当被修饰的变量指向变量释放或置空,会出现野指针错误!

    weak:只能修饰对象,不会出现野指针错误,当被修饰的变量指向的变量释放或是置空,被修饰变量指向nil,不会出现野指针错误。

    引申

    ***** 内存分析

    静态内存分析 analyze、分析/ 蓝色

    例如:逻辑错误

    logic error  /  Dead store/Memory

    不是太准 不可变赋值给可变数组 ,调方法时候传入的字典参数未实例化

    动态内存分析 profile -allocation /leaks   侧面/分配/泄漏

    *****手势 响应者链条

    分两块,

    1 定位接收者

    2 响应者链条

    1定位接收者 当点击屏幕的ui出发一个事件,流程是事件添加到UIAplication的事件组,传递事件经历 window ,父控件且判断控件是否接受事件,如果是,则父控件遍历子控件,判断当前出发点是否在子控件上,继续遍历直到找到触发该点的最后一个子控件,事件传递不可以断,以为这所有控件务必可以处理事件,获取执行触发事件的控件。 

    ps:这就说明了 为什么交互期间中间有个什么uiimageview等不能交互的夫控件,导致子控件不接受响应事件

    可以接受响应事件的控件需要继承uiresponder 但还不够 需要可以交互 不是隐藏的 alpha值不是太小

    2 响应者链条,功能是一个事件的发生,可以被多个控件获取。回传靠的是super执行方法

    举例子:view上事件触发 默认事件互传给父控件,继续回传父控件,控制器.view 控制器(一样继承uiresponder);如果控制器还有父控制器那就父控件传递 给控制器 然后self.view 然后父控制器 window uiapplication 

    *****注册登录 加密流程 对称非对称加密

    *****get post tcp udp

    *****缓存策略

    *****镂空的遮罩

         0 思路:蒙版.layer.mask = layer对象

         1 创建蒙版

         2 绘制贝塞尔路径 添加反转图形(叠加部分会镂空)

         3 创建layer(CAShapeLayer子类).path = 贝塞尔路径.path

         4 设置 蒙版.layer.mask = layer对象

    *****ios webp格式图片应用 及交互

    博客园详解

    ***** ios 堆栈详解

    博客园详解

  • 相关阅读:
    PerfDog携手Imagination,助力开发者获取GPU关键数据
    WeTest云手机升级,支持iOS 15全新系统
    洞穿性能测试痛点,PerfDog以提升应用和游戏的品质为使命
    使用xmlhttprequest遇到CORS报错的处理
    Hive的联级(cascade)-新增字段(column)后,旧分区无法更新数据问题
    数据异常检测入门
    Linux查看文件或文件夹大小: du命令
    k8s pod自动重启原因(jvm内存设置)
    计算容器运行至今多长时间
    期刊论文在线投稿审稿系统day1数据库设计
  • 原文地址:https://www.cnblogs.com/ly1973/p/7063912.html
Copyright © 2011-2022 走看看