程序员头条
2015-08-14 15:42
686 查看
推荐:iOS面试题集锦 | 程序员头条
归档
分类
标签
关于
Search
By
2015-07-26
更新日期:2015-07-27
以下是我的的修正版本:
线程安全:
内存管理:
访问权限:
指定方法名:
不常用的:
什么情况使用 weak 关键字,相比 assign 有什么不同?
在ARC下使用block引起循环引用时,需要使用weak。
属性使用
怎么用 copy 关键字?
一般使用
而使用
常用于NSString和Block。
这个写法会出什么问题:
当一个NSMutableArray对象使用
如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
该类必须要实现NSCopying协议。实现
重写copy关键字的setter时,需要调用一下传入对象的copy方法。然后赋值给该setter的方法对应的成员变量。
这一套问题区分度比较大,如果上面的问题都能回答正确,可以延伸问更深入点的
@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的.
property在编译时编译器会自动的为我们生成一个私有的成员变量和setter与getter方法的声明和实现。反编译property大致生成五个东西
OBJCIVAR类名类名属性名称 该属性的偏移量
setter与getter方法对应的实现函数
ivar_list 就是成员变量列表
method_list 方法列表
prop_list 属性列表
也就是说我们每次在增加一个属性,系统都会在ivar_list中添加一个成员变量的描述,在method_list中增加setter与getter方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后产生setter与getter方法对应的实现,在setter方法方法中从偏移量的位置开始赋值,在getter方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转。
@protocol 和 category 中如何使用 @property
在protocol中使用property只会生成setter和getter方法声明,我们使用属性的目的,是希望遵守我协议的对象的实现该属性
category 使用 @property 也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行Objective-C动态运行机制中的两个函数:
objc_setAssociatedObject
objc_getAssociatedObject
runtime 如何实现 weak 属性
objc_storeWeak函数把第二个参数的赋值对象的地址作为键值,将第一个参数的weak修饰的属性变量的地址注册到weak表中。如果第二个参数为0,那么把变量的地址从weak表中删除,在后面的相关一题会详解。
同上
[※]weak属性需要在dealloc中置nil么?
不需要,在ARC环境无论是强指针还是弱指针都无需在dealloc设置为nil,ARC会自动帮我们处理.
[※※]@synthesize和@dynamic分别有什么作用?
@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = var,var为property变量。可以手动修改属性var对应的实例变量。例如:@syntheszie var = var1
@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法, 在Xcode4.4之后的版本可以省略不写.
@dynamic告诉编译器不要自动生成成员变量的getter和setter方法,而是开发者自己手工生成或者运行时生成.
[※※※]ARC下,不显示指定任何属性关键字时,默认的关键字都有哪些?
基本数据类型:
普通的Objective-C对象:
[※※※]用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
使用
如果使用
[※※※]@synthesize合成实例变量的规则是什么?假如property名为foo,存在一个名为_foo的实例变量,那么还会自动合成新变量么?
如果没有指定实例变量的名称,就会默认自动生成一个与属性同名的并在前面加一条下划线的实例变量.
如果指定了实例变量名称,刚好与属性自动合成的实例变量名称相同,那就该属性就不自动合成实例变量了。
默认的是 @synthesize foo = _foo; 属性就不会自动生成实例变量了.
如果使用 @synthesize foo = _foo1; 属性不会自动生成实例变量,而且成员变量被修改为_foo1, 使用点语法set属性成员变量的值会赋值给_foo1,而不是_foo.
[※※※※※]在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
@synthesize主要就是用来生成setter,getter方法的实现,在@property被增强之后,已经很少使用@synthesize了.
[※※]objc中向一个nil对象发送消息将会发生什么?
objc向nil发送消息是有效的,只是在运行时不会有什么作用.
如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)。
如果方法返回值为指针类型,其指针大小为小于或者等于sizeof(void*),float,double,long double 或者long long的整型标量,发送给nil的消息将返回0。
如果方法返回值为结构体,发送给nil的消息将返回0。结构体中各个字段的值将都是0。
如果方法的返回值不是上述提到的几种情况,那么发送给nil的消息的返回值将是未定义的。
[※※※]objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
[obj foo]变量编译之后就是objc_msgSend()函数的调用。该方法编译后的形式大致如下:
objc_msgSend(obj, sel_registerName(“foo”));
[※※※]什么时候会报unrecognized selector的异常?
当类或者对象使用到某个声明过的方法,而这个方法不管自己类还是在父类里都没有实现的时候。
[※※※※]一个objc对象如何进行内存布局?(考虑有父类的情况)
每一个objc对象都是一个类的实例。在Objective-C语言的内部,每一个对象都有一个名为isa的指针,指向该对象的类(类对象)。每一个类描述了一系列它的实例的特点,包括成员变量的列表,成员函数的列表等。每一个对象都可以接受消息,而对象能够接收的消息列表是保存在它所对应的类对象中。如下图:
类对象内部还有一个指向superclass的指针,指向他的父类对象,根类为NSObject类它的superclass指针指向nil,如下图:
类对象既然称为对象那它也是一个实例。类对象中也有一个isa指针指向它的元类(meta class),即类对象是元类的实例。元类内部存放的是类方法列表,根元类的isa指针指向自己,superclass指针指向NSObject类。
[※※※※]一个objc对象的isa的指针指向什么?有什么作用?
objc对象的isa指针指向类对象,用于寻找对象的方法。
[※※※※]下面的代码输出什么?
[※※※※]runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)
每一个类对象中都一个方法列表,方法列表中记录着方法的名称,方法实现,以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现.
[※※※※]使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?
在ARC下不需要
在MRC中,对于使用retain或copy策略的时候需要释放
[※※※※※]objc中的类方法和实例方法有什么本质区别和联系?
类方法
类方法保存在类对象的元类中
类方法只能通过类对象调用
类方法中的self是类对象
类方法中不能访问成员变量
类方法中不能直接调用对象方法
实例方法
保存在类对象的对象模型中
实例方法只能通过实例对象调用
实例方法中的self是实例对象
实例方法中可以访问成员变量
实例方法中可以访问成员变量
实例方法中可以访问成员变量
[※※※※※]_objc_msgForward函数是做什么的,直接调用它将会发生什么?
这个没接触过,也没找到相关资料。但是跟objc动态运行机制中的
[※※※※※]runtime如何实现weak变量的自动置nil?
[※※※※※]能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
Objective-C不支持往已存在的类中添加实例变量
可以向运行时创建的类中添加实例变量。参考
[※※※]runloop和线程有什么关系?
runloop是线程的基础架构。每个线程,包括程序的主线程(main thread)都有与之相应的run loop对象.
主线程的runloop默认是启动的。
对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动.
可以通过NSRunLoop的
[※※※]runloop的mode作用是什么?
*NSDefaultRunLoopMode 缺省情况下,将包含所有操作,并且大多数情况下都会使用此模式
NSConnectionReplyMode 此模式用于处理NSConnection的回调事件
NSModalPanelRunLoopMode 模态模式,此模式下,RunLoop只对处理模态相关事件
NSModalPanelRunLoopMode 此模式用于处理NSConnection的回调事件
NSRunLoopCommonModes 此模式用于配置”组模式”,一个输入源与此模式关联,则输入源与组中的所有模式相关联。
[※※※※]以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
当前主线程的 RunLoop 正在以
常见的解决方案是把Timer“绑定”到
这样这个Timer就可以和当前组中的两种模式
[※※※※※]猜想runloop内部是如何实现的?
*runloop是一个死循环
如果事件队列中存放在着事件,就会取出事件执行。
如果没有事件,就挂起,等有事件了,唤醒循环,开始执行.
[※]objc使用什么机制管理对象内存?
MRC 手动引用计数
ARC 自动引用计数
[※※※※]ARC通过什么方式帮助开发者管理内存?
在编译器编译器为开发者添加内存管理的代码。
[※※※※]不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)
在每次事件循环开始创建自动释放池,在每次事件结束销毁自动释放池.
在viewDidLoad中创建的,是在viewWillAppear和viewDidApper之间系统执行
[※※※※]BAD_ACCESS在什么情况下出现?
对一个已经释放的对象执行了release
执行了死循环
[※※※※※]苹果是如何实现autoreleasepool的?
autoreleasepool以一个队列数组的形式实现,主要通过下列三个函数完成.
objc_autoreleasepoolPush
objc_autoreleasepoolPop
objc_aurorelease
看函数名就可以知道,对autorelease分别执行push,和pop操作。销毁对象时执行release操作。
[※※]使用block时什么情况会发生引用循环,如何解决?
一个对象中强引用了block,在block中又使用了该对象,就会发射循环引用。
解决方法是将该对象使用
id weak weakSelf = self;
或者 weak __typeof(&*self)weakSelf = self该方法可以设置宏
id __block weakSelf = self;
[※※]在block内如何修改block外部变量?
外部变量使用__block修饰
[※※※]使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
一般不用考虑,因为官方文档中没有告诉我们要注意发生强引用,所以推测系统控件一般没有对这些block进行强引用,所以我们可以不用考虑循环强引用的问题
[※※]GCD的队列(dispatch_queue_t)分哪两种类型?
串行队列Serial Dispatch Queue
并行队列Concurrent Dispatch Queue
[※※※※]如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
dispatch_barrier_async函数会等待追加到Concurrent Dispatch Queue并行队列中的操作全部执行完之后,然后再执行dispatch_barrier_async函数追加的处理,等dispatch_barrier_async追加的处理执行结束之后,Concurrent Dispatch Queue才恢复之前的动作继续执行。
打个比方:比如你在看电视每个台都在播放精彩的内容,突然插进来一则广告。于是你就换台,结果发现每个台都在放这个广告,等这个广告播放完之后,各个台才开始恢复原来播放的内容。dispatch_barrier_async函数追加的内容就如这条广告。
[※※※※※]苹果为什么要废弃dispatch_get_current_queue?
dispatch_get_current_queue容易造成死锁
[※※※※※]以下代码运行结果如何?
只输出:1 。发生主线程锁死。
[※※]addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?
给这个value设置一个值,就可以触发了
[※※※]若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key?
都可以
[※※※※]KVC的keyPath中的集合运算符如何使用?
必须用在集合对象上或普通对象的集合属性上
简单集合运算符有@avg, @count , @max , @min ,@sum,
格式 @”@sum.age”或 @”集合属性.@max.age”
[※※※※]KVC和KVO的keyPath一定是属性么?
KVO支持实例变量
[※※※※※]如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?
如何自己动手实现 KVO
[※※※※※]apple用什么方式实现对一个对象的KVO?
上一题已包含
[※※]IBOutlet连出来的视图属性为什么可以被设置成weak?
因为既然有外链那么视图在xib或者storyboard中肯定存在,视图已经对它有一个强引用了。
[※※※※※]IB中User Defined Runtime Attributes如何使用?
它能够通过KVC的方式配置一些你在interface builder 中不能配置的属性。当你希望在IB中作尽可能多得事情,这个特性能够帮助你编写更加轻量级的viewcontroller
[※※※]如何调试BAD_ACCESS错误
重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object
通过NSZombieEnabled
设置全局断点快速定位问题代码所在行
[※※※]lldb(gdb)常用的调试命令?
breakpoint 设置断点定位到某一个函数
n 断点指针下一步
po打印对象
本文由程序员头条管理员蒋小飞原创文章,转载务必注明出处。
蒋小飞微信公众号iOSTalk:JoneTalk
我叫小飞,iOS开发者,现就职于智能家居领域,坐标浙江杭州.iOSTalk用于记录iOS开发技巧,以及发表个人成长之路的一些观点.
参考链接http://www.jianshu.com/p/4fea8fa60d75
http://draveness.me/guan-yu-xie-ios-wen-ti-de-jie-da/
http://stackoverflow.com/questions/14856681/why-does-a-copy-nonatomic-nsmutablearray-property-create-nsarrays
http://blog.devtang.com/blog/2013/10/15/objective-c-object-model;
http://blog.cnbluebox.com/blog/2014/07/01/cocoashen-ru-xue-xi-nsoperationqueuehe-nsoperationyuan-li-he-shi-yong
http://mobile.51cto.com/iphone-279455.htm
/*700*350 创建于 2015-08-01*/
var cpro_id = "u2239724";
本文出处程序员头条:http://www.90159.com/2015/07/26/71/
转载请在开头注明本文出处。
欢迎关注本站微信公众号:为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等.并不定期奉送各种福利.
微信公众号猿圈:CodePush
iOS开发面试
iOS开发
PREVIOUS:
16则极具内涵的程序猿幽默
NEXT:
不要在init和dealloc函数中使用accessor
文章目录
程序员头条
程序员关心的才是头条
代码规范
一个区分很大的面试题
CheckList
参考链接
var cpro_id="u2238843";
(window["cproStyleApi"] = window["cproStyleApi"] || {})[cpro_id]={at:"3",rsi0:"250",rsi1:"250",pat:"17",tn:"baiduCustNativeAD",rss1:"#FFFFFF",conBW:"1",adp:"1",ptt:"0",titFF:"%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91",titFS:"14",rss2:"#000000",titSU:"0"}
公众号猿圈:CodePush
公众号iOS开发:iOSDevTip
分类
Android开发16
Linux4
Nodejs1
PHP3
Python6
Swift1
git6
iOS开发65
swift3
云计算/大数据3
互联网11
产品/设计1
其他1
创业5
幽默5
程序人生11
编程语言7
职场8
面试技巧3
标签
1亿美金1
APP1
Android7
Android Studio1
Android开发11
Animation1
Apache1
AutoLayout2
Autolayout1
Block1
CADisplayLink1
CEO1
Category1
Client1
CocoaPods1
Core Animation1
Core Audio1
Core Data1
CrashLog1
Data Binding1
友情链接
刚刚在线
程序员头条
swift开发
APP开发者
程序员聚合网站
阳和移动开发
Android开发中文站
爱程序网
IT技术文章
Hexo
RSS 订阅
热门推荐
var cpro_id="u2240637";
(window["cproStyleApi"] = window["cproStyleApi"] || {})[cpro_id]={at:"3",rsi0:"250",rsi1:"350",pat:"6",tn:"baiduCustNativeAD",rss1:"#FFFFFF",conBW:"1",adp:"1",ptt:"0",titFF:"%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91",titFS:"14",rss2:"#000000",titSU:"0",ptbg:"90",piw:"0",pih:"0",ptp:"0"}
Powered by hexo and Theme by Pacman © 2015
程序员头条
(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else
{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
$('#toc.toc-aside').css('display', 'none');
}
});
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
});(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else
{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
$('#toc.toc-aside').css('display', 'none');
}
});
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
});
(document).ready(function(){
var ai = (′.article−content>iframe′),ae=('.article-content>iframe'),
ae = ('.article-content>embed'),
t = ('#toc'),
h =('#toc'),
h = ('article h2')
ah = (′articleh2′),ta=('article h2'),
ta = ('#toc.toc-aside'),
o = (′.openaside′),c=('.openaside'),
c = ('.closeaside');
if(ai.length>0){
ai.wrap('');
};
if(ae.length>0){
ae.wrap('');
};
if(ah.length==0){
t.css('display','none');
}else{
c.click(function(){
ta.css('display', 'block').addClass('fadeIn');
});
o.click(function(){
ta.css('display', 'none');
});
(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
};
});(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
};
});
(document).ready(function(){
var this=this = ('.share'),
url = this.attr(′data−url′),encodedUrl=encodeURIComponent(url),title=this.attr('data-url'),
encodedUrl = encodeURIComponent(url),
title = this.attr('data-title'),
tsina = $this.attr('data-tsina');
var html = [
'',
'扫描二维码分享到微信朋友圈Loading...Please wait',
'',
'',
'',
'',
'',
''
].join('');
this.append(html);this.append(html);
('.article-share-qrcode').click(function(){
var imgSrc = ('#qrcode-pic').attr('data-src');('#qrcode-pic').attr('data-src');
('#qrcode-pic').attr('src', imgSrc);
('#qrcode-pic').load(function(){('#qrcode-pic').load(function(){
('.qrcode strong').text(' ');
});
});
});
var duoshuoQuery = {short_name:"90159"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = '//static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
程序员头条
程序员关心的,才是头条!
主页归档
分类
标签
关于
Search
[code]</header> <div id="container"> <div id="main" class="post" itemscope itemprop="blogPost"> <article itemprop="articleBody"> <header class="article-info clearfix">
[code] <a href="/2015/07/26/71/" title="推荐:iOS面试题集锦" itemprop="url">推荐:iOS面试题集锦</a>
By
[code] <a href="http://www.90159.com" title="程序员头条">程序员头条</a> </p>
2015-07-26
更新日期:2015-07-27
[code] <div id="toc" class="toc-article"> <strong class="toc-title">文章目录</strong> <ol class="toc"><li class="toc-item toc-level-4"><a class="toc-link" href="#代码规范"><span class="toc-number">1.</span> <span class="toc-text">代码规范</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#一个区分很大的面试题"><span class="toc-number">2.</span> <span class="toc-text">一个区分很大的面试题</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#CheckList"><span class="toc-number">3.</span> <span class="toc-text">CheckList</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#参考链接"><span class="toc-number">3.0.1.</span> <span class="toc-text">参考链接</span></a></li></ol></li></ol></li></ol> </div> <p>这是百度一位iOS开发者<a href="http://weibo.com/u/1364395395" target="_blank" rel="external">@sunnyxx</a>提的面试题,由<a href="http://weibo.com/tangqiaoboy?from=page_100505_profile&wvr=6&mod=myfollowhisfan" target="_blank" rel="external">@唐巧</a>转发到他的微信公众号里看到,说回答的好可以赠送一本价值79元的《iOS应用安全攻防实战》。动力满满的就搞起来,结果在我最后期限的前几分钟整理图片的时候不小心点了个 <strong>X</strong> 把整片文章都删了。虽然说不少答案是参考查阅的,那也整了我一天的好吗。后来想想能尝到这种崩溃的感觉还是挺不错的!有后来是因为没想到跟 <strong>X</strong> 网页一样的删除还能从垃圾桶捡回来。兴奋的打开一看,XX全是乱码!不对仔细一看我的内容还在躺在乱码中朝我呼喊呢!扯淡完毕,以下答案是经过一番查阅资料以及自己一些补充理解之后,整理出来的,如有不对之处欢迎指正和补充。其中大部分的答案来自<a href="http://www.jianshu.com/p/4fea8fa60d75" target="_blank" rel="external">这里</a>非常感谢@满山李子前辈。</p>
代码规范
风格纠错原题:以下是我的的修正版本:
一个区分很大的面试题
@property 后面可以有哪些修饰符?线程安全:
nonatomic,
atomic
内存管理:
strong,
weak,
copy,
retain,
unsafe_unretained,
assign
访问权限:
readonly,
readwrite
指定方法名:
getter=,
setter=
不常用的:
nonnull,
null_resettable,
nullable
什么情况使用 weak 关键字,相比 assign 有什么不同?
在ARC下使用block引起循环引用时,需要使用weak。
属性使用
IBOutlet时,使用weak关键字修饰。
assign用于简单的赋值,不改变属性的引用计数,用于Objective-C中的NSInteger, CGFloat。以及C语言中的int, float, double等数据类型。
weak用于对象类型,同样不改变对象的引用计数且不持对象。当该对象废弃时,该弱引用失效并自动的将指针变量赋值为nil,可以避免循环引用。
怎么用 copy 关键字?
一般使用
retain或者
strong修饰属性时,是使引用对象的指针指向同一个对象,即为同一块内存地址。只要其中有一个指针变量被修改时所有其他引用该对象的变量都会被改变。
而使用
copy关键字修饰在赋值时是释放旧对象,拷贝新对象内容。重新分配了内存地址。以后该指针变量被修改时就不会影响旧对象的内容了。
copy只有实现NSCopying协议的对象类型才有效。
常用于NSString和Block。
这个写法会出什么问题:
@@property (copy) NSMutableArray *array;
当一个NSMutableArray对象使用
initWithArray:初始化方法创建时,并将该对象赋值给了array属性。那么之后array执行可变数组的方法,比如:
removeObjectAtIndex:时会出现unrecognized selector sent to instance的崩溃。原因在于array属性在被赋值(setter)的时候默认执行了copy方法后变为了不可变NSArray对象。
如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
该类必须要实现NSCopying协议。实现
- (id)copyWithZone:(NSZone *)zone;方法。
重写copy关键字的setter时,需要调用一下传入对象的copy方法。然后赋值给该setter的方法对应的成员变量。
这一套问题区分度比较大,如果上面的问题都能回答正确,可以延伸问更深入点的
@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的.
property在编译时编译器会自动的为我们生成一个私有的成员变量和setter与getter方法的声明和实现。反编译property大致生成五个东西
OBJCIVAR类名类名属性名称 该属性的偏移量
setter与getter方法对应的实现函数
ivar_list 就是成员变量列表
method_list 方法列表
prop_list 属性列表
也就是说我们每次在增加一个属性,系统都会在ivar_list中添加一个成员变量的描述,在method_list中增加setter与getter方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后产生setter与getter方法对应的实现,在setter方法方法中从偏移量的位置开始赋值,在getter方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转。
@protocol 和 category 中如何使用 @property
在protocol中使用property只会生成setter和getter方法声明,我们使用属性的目的,是希望遵守我协议的对象的实现该属性
category 使用 @property 也是只会生成setter和getter方法的声明,如果我们真的需要给category增加属性的实现,需要借助于运行Objective-C动态运行机制中的两个函数:
objc_setAssociatedObject
objc_getAssociatedObject
runtime 如何实现 weak 属性
[code]// 模拟代码 id obj1; obj1 = 0; objc_storeWeak(&obj1, obj); objc_storeWeak(&obj1);
objc_storeWeak函数把第二个参数的赋值对象的地址作为键值,将第一个参数的weak修饰的属性变量的地址注册到weak表中。如果第二个参数为0,那么把变量的地址从weak表中删除,在后面的相关一题会详解。
CheckList
[※]@property中有哪些属性关键字?同上
[※]weak属性需要在dealloc中置nil么?
不需要,在ARC环境无论是强指针还是弱指针都无需在dealloc设置为nil,ARC会自动帮我们处理.
[※※]@synthesize和@dynamic分别有什么作用?
@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = var,var为property变量。可以手动修改属性var对应的实例变量。例如:@syntheszie var = var1
@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法, 在Xcode4.4之后的版本可以省略不写.
@dynamic告诉编译器不要自动生成成员变量的getter和setter方法,而是开发者自己手工生成或者运行时生成.
[※※※]ARC下,不显示指定任何属性关键字时,默认的关键字都有哪些?
基本数据类型:
atomic,
readwrite``,assign`
普通的Objective-C对象:
atomic,
readwrite,
strong
[※※※]用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
使用
copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.
如果使用
strong.这个属性有可能指向一个可变对象,如果这个可变对象被外部意外的修改了,由于可变对象被改变之后起始地址不会发生变化。而附有strong修饰的属性依然指向这这块内存地址,下次读取的时候就会是被改变以后的对象了.也就是说如果使用
strong可能会被外部意外的修改。
[※※※]@synthesize合成实例变量的规则是什么?假如property名为foo,存在一个名为_foo的实例变量,那么还会自动合成新变量么?
如果没有指定实例变量的名称,就会默认自动生成一个与属性同名的并在前面加一条下划线的实例变量.
如果指定了实例变量名称,刚好与属性自动合成的实例变量名称相同,那就该属性就不自动合成实例变量了。
默认的是 @synthesize foo = _foo; 属性就不会自动生成实例变量了.
如果使用 @synthesize foo = _foo1; 属性不会自动生成实例变量,而且成员变量被修改为_foo1, 使用点语法set属性成员变量的值会赋值给_foo1,而不是_foo.
[※※※※※]在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
@synthesize主要就是用来生成setter,getter方法的实现,在@property被增强之后,已经很少使用@synthesize了.
[※※]objc中向一个nil对象发送消息将会发生什么?
objc向nil发送消息是有效的,只是在运行时不会有什么作用.
如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)。
如果方法返回值为指针类型,其指针大小为小于或者等于sizeof(void*),float,double,long double 或者long long的整型标量,发送给nil的消息将返回0。
如果方法返回值为结构体,发送给nil的消息将返回0。结构体中各个字段的值将都是0。
如果方法的返回值不是上述提到的几种情况,那么发送给nil的消息的返回值将是未定义的。
[※※※]objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
[obj foo]变量编译之后就是objc_msgSend()函数的调用。该方法编译后的形式大致如下:
objc_msgSend(obj, sel_registerName(“foo”));
[※※※]什么时候会报unrecognized selector的异常?
当类或者对象使用到某个声明过的方法,而这个方法不管自己类还是在父类里都没有实现的时候。
[※※※※]一个objc对象如何进行内存布局?(考虑有父类的情况)
每一个objc对象都是一个类的实例。在Objective-C语言的内部,每一个对象都有一个名为isa的指针,指向该对象的类(类对象)。每一个类描述了一系列它的实例的特点,包括成员变量的列表,成员函数的列表等。每一个对象都可以接受消息,而对象能够接收的消息列表是保存在它所对应的类对象中。如下图:
类对象内部还有一个指向superclass的指针,指向他的父类对象,根类为NSObject类它的superclass指针指向nil,如下图:
类对象既然称为对象那它也是一个实例。类对象中也有一个isa指针指向它的元类(meta class),即类对象是元类的实例。元类内部存放的是类方法列表,根元类的isa指针指向自己,superclass指针指向NSObject类。
[※※※※]一个objc对象的isa的指针指向什么?有什么作用?
objc对象的isa指针指向类对象,用于寻找对象的方法。
[※※※※]下面的代码输出什么?
[code]@ implementation Son : Father - (id)init { self = [super init]; if (self) { NSLog(@"%@", NSStringFromClass([self class])); NSLog(@"%@", NSStringFromClass([super class])); } return self; } @ end输出的都是:Son
[※※※※]runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)
每一个类对象中都一个方法列表,方法列表中记录着方法的名称,方法实现,以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现.
[※※※※]使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?
在ARC下不需要
在MRC中,对于使用retain或copy策略的时候需要释放
[※※※※※]objc中的类方法和实例方法有什么本质区别和联系?
类方法
类方法保存在类对象的元类中
类方法只能通过类对象调用
类方法中的self是类对象
类方法中不能访问成员变量
类方法中不能直接调用对象方法
实例方法
保存在类对象的对象模型中
实例方法只能通过实例对象调用
实例方法中的self是实例对象
实例方法中可以访问成员变量
实例方法中可以访问成员变量
实例方法中可以访问成员变量
[※※※※※]_objc_msgForward函数是做什么的,直接调用它将会发生什么?
这个没接触过,也没找到相关资料。但是跟objc动态运行机制中的
forwardingTargetForSelector:和
forwardInvocation:方法有点相似。猜测是该方法编译后的源码,都用于消息转发机制。
[※※※※※]runtime如何实现weak变量的自动置nil?
[code]/* 编译器的模拟源代码 */ id obj1; objc_initWeak(&obj1, obj); objc_destroyWeak(&obj1);通过objc_initWeak函数初始化附有weak修饰符的变量,在变量作用域结束时通过objc_destoryWeak函数释放该变量。objc_initWeak函数将附有weak修饰符的变量初始化为0后,将会赋值的对象作为参数调用objc_storeWeak函数。
[code]obj1 = 0; obj_storeWeak(&obj1, obj);然后obj_destroyWeak函数将0作为参数的调用objc_storeWeak函数。
[code]obj_destroyWeak(&obj1, 0);前面的源代码与下列源代码相同。
[code]/ * 编译器的模拟代码 */ id obj1; obj1 = 0; objc_storeWeak&obj1, obj); objc_storeWeak(&obj1, 0);objc_storeWeak函数的第二参数的赋值对象的地址作为键值,将第一个参数的附有__weak修饰符的变量的地址注册到weak表中。如果第二参数为0,则把变量的地址从weak表中删除。
[※※※※※]能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
Objective-C不支持往已存在的类中添加实例变量
可以向运行时创建的类中添加实例变量。参考
[※※※]runloop和线程有什么关系?
runloop是线程的基础架构。每个线程,包括程序的主线程(main thread)都有与之相应的run loop对象.
主线程的runloop默认是启动的。
对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动.
可以通过NSRunLoop的
currentRunLoop类方法来获取当前线程的runloop
[※※※]runloop的mode作用是什么?
*NSDefaultRunLoopMode 缺省情况下,将包含所有操作,并且大多数情况下都会使用此模式
NSConnectionReplyMode 此模式用于处理NSConnection的回调事件
NSModalPanelRunLoopMode 模态模式,此模式下,RunLoop只对处理模态相关事件
NSModalPanelRunLoopMode 此模式用于处理NSConnection的回调事件
NSRunLoopCommonModes 此模式用于配置”组模式”,一个输入源与此模式关联,则输入源与组中的所有模式相关联。
[※※※※]以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
当前主线程的 RunLoop 正在以
UITrackingRunLoopMode的模式运行。 这个时候 RunLoop 只会处理与
UITrackingRunLoopMode“绑定”的源, 比如触摸、滚动等事件;而 NSTimer 是默认“绑定”到
NSRunLoopDefaultMode上的, 所以 Timer 是事情是不会被 RunLoop 处理的,定时器被暂停了!
常见的解决方案是把Timer“绑定”到
NSRunLoopCommonModes模式上:
[code][[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];>
这样这个Timer就可以和当前组中的两种模式
UITrackingRunLoopMode和
kCFRunLoopDefaultMode相关联了。 RunLoop在这两种模式下,Timer都可以正常运行了。
[※※※※※]猜想runloop内部是如何实现的?
*runloop是一个死循环
如果事件队列中存放在着事件,就会取出事件执行。
如果没有事件,就挂起,等有事件了,唤醒循环,开始执行.
[※]objc使用什么机制管理对象内存?
MRC 手动引用计数
ARC 自动引用计数
[※※※※]ARC通过什么方式帮助开发者管理内存?
在编译器编译器为开发者添加内存管理的代码。
[※※※※]不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)
在每次事件循环开始创建自动释放池,在每次事件结束销毁自动释放池.
在viewDidLoad中创建的,是在viewWillAppear和viewDidApper之间系统执行
[pool drain]操作的时候释放对象的。
[※※※※]BAD_ACCESS在什么情况下出现?
对一个已经释放的对象执行了release
执行了死循环
[※※※※※]苹果是如何实现autoreleasepool的?
autoreleasepool以一个队列数组的形式实现,主要通过下列三个函数完成.
objc_autoreleasepoolPush
objc_autoreleasepoolPop
objc_aurorelease
看函数名就可以知道,对autorelease分别执行push,和pop操作。销毁对象时执行release操作。
[※※]使用block时什么情况会发生引用循环,如何解决?
一个对象中强引用了block,在block中又使用了该对象,就会发射循环引用。
解决方法是将该对象使用
__weak或者
__block修饰符修饰之后再在block中使用。
id weak weakSelf = self;
或者 weak __typeof(&*self)weakSelf = self该方法可以设置宏
id __block weakSelf = self;
[※※]在block内如何修改block外部变量?
外部变量使用__block修饰
[※※※]使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
一般不用考虑,因为官方文档中没有告诉我们要注意发生强引用,所以推测系统控件一般没有对这些block进行强引用,所以我们可以不用考虑循环强引用的问题
[※※]GCD的队列(dispatch_queue_t)分哪两种类型?
串行队列Serial Dispatch Queue
并行队列Concurrent Dispatch Queue
[※※※※]如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
[code]dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ /*加载图片1 */ }); dispatch_group_async(group, queue, ^{ /*加载图片2 */ }); dispatch_group_async(group, queue, ^{ /*加载图片3 */ }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 合并图片 });[※※※※]dispatch_barrier_async的作用是什么?
dispatch_barrier_async函数会等待追加到Concurrent Dispatch Queue并行队列中的操作全部执行完之后,然后再执行dispatch_barrier_async函数追加的处理,等dispatch_barrier_async追加的处理执行结束之后,Concurrent Dispatch Queue才恢复之前的动作继续执行。
打个比方:比如你在看电视每个台都在播放精彩的内容,突然插进来一则广告。于是你就换台,结果发现每个台都在放这个广告,等这个广告播放完之后,各个台才开始恢复原来播放的内容。dispatch_barrier_async函数追加的内容就如这条广告。
[※※※※※]苹果为什么要废弃dispatch_get_current_queue?
dispatch_get_current_queue容易造成死锁
[※※※※※]以下代码运行结果如何?
[code]- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2"); }); NSLog(@"3"); }
只输出:1 。发生主线程锁死。
[※※]addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?
[code] // 添加键值观察 /* 1 观察者,负责处理监听事件的对象 2 观察的属性 3 观察的选项 4 上下文 */ [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];observer中需要实现一下方法:
[code]// 所有的 kvo 监听到事件,都会调用此方法 /* 1. 观察的属性 2. 观察的对象 3. change 属性变化字典(新/旧) 4. 上下文,与监听的时候传递的一致 */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context[※※※]如何手动触发一个value的KVO
给这个value设置一个值,就可以触发了
[※※※]若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key?
都可以
[※※※※]KVC的keyPath中的集合运算符如何使用?
必须用在集合对象上或普通对象的集合属性上
简单集合运算符有@avg, @count , @max , @min ,@sum,
格式 @”@sum.age”或 @”集合属性.@max.age”
[※※※※]KVC和KVO的keyPath一定是属性么?
KVO支持实例变量
[※※※※※]如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?
如何自己动手实现 KVO
[※※※※※]apple用什么方式实现对一个对象的KVO?
上一题已包含
[※※]IBOutlet连出来的视图属性为什么可以被设置成weak?
因为既然有外链那么视图在xib或者storyboard中肯定存在,视图已经对它有一个强引用了。
[※※※※※]IB中User Defined Runtime Attributes如何使用?
它能够通过KVC的方式配置一些你在interface builder 中不能配置的属性。当你希望在IB中作尽可能多得事情,这个特性能够帮助你编写更加轻量级的viewcontroller
[※※※]如何调试BAD_ACCESS错误
重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object
通过NSZombieEnabled
设置全局断点快速定位问题代码所在行
[※※※]lldb(gdb)常用的调试命令?
breakpoint 设置断点定位到某一个函数
n 断点指针下一步
po打印对象
本文由程序员头条管理员蒋小飞原创文章,转载务必注明出处。
蒋小飞微信公众号iOSTalk:JoneTalk
我叫小飞,iOS开发者,现就职于智能家居领域,坐标浙江杭州.iOSTalk用于记录iOS开发技巧,以及发表个人成长之路的一些观点.
参考链接http://www.jianshu.com/p/4fea8fa60d75
http://draveness.me/guan-yu-xie-ios-wen-ti-de-jie-da/
http://stackoverflow.com/questions/14856681/why-does-a-copy-nonatomic-nsmutablearray-property-create-nsarrays
http://blog.devtang.com/blog/2013/10/15/objective-c-object-model;
http://blog.cnbluebox.com/blog/2014/07/01/cocoashen-ru-xue-xi-nsoperationqueuehe-nsoperationyuan-li-he-shi-yong
http://mobile.51cto.com/iphone-279455.htm
/*700*350 创建于 2015-08-01*/
var cpro_id = "u2239724";
本文出处程序员头条:http://www.90159.com/2015/07/26/71/
转载请在开头注明本文出处。
欢迎关注本站微信公众号:为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等.并不定期奉送各种福利.
微信公众号猿圈:CodePush
[code]</div> <footer class="article-footer clearfix">
iOS开发面试
iOS开发
PREVIOUS:
16则极具内涵的程序猿幽默
NEXT:
不要在init和dealloc函数中使用accessor
文章目录
程序员头条
程序员关心的才是头条
代码规范
一个区分很大的面试题
CheckList
参考链接
var cpro_id="u2238843";
(window["cproStyleApi"] = window["cproStyleApi"] || {})[cpro_id]={at:"3",rsi0:"250",rsi1:"250",pat:"17",tn:"baiduCustNativeAD",rss1:"#FFFFFF",conBW:"1",adp:"1",ptt:"0",titFF:"%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91",titFS:"14",rss2:"#000000",titSU:"0"}
公众号猿圈:CodePush
公众号iOS开发:iOSDevTip
分类
Android开发16
Linux4
Nodejs1
PHP3
Python6
Swift1
git6
iOS开发65
swift3
云计算/大数据3
互联网11
产品/设计1
其他1
创业5
幽默5
程序人生11
编程语言7
职场8
面试技巧3
标签
1亿美金1
APP1
Android7
Android Studio1
Android开发11
Animation1
Apache1
AutoLayout2
Autolayout1
Block1
CADisplayLink1
CEO1
Category1
Client1
CocoaPods1
Core Animation1
Core Audio1
Core Data1
CrashLog1
Data Binding1
友情链接
刚刚在线
程序员头条
swift开发
APP开发者
程序员聚合网站
阳和移动开发
Android开发中文站
爱程序网
IT技术文章
Hexo
RSS 订阅
热门推荐
var cpro_id="u2240637";
(window["cproStyleApi"] = window["cproStyleApi"] || {})[cpro_id]={at:"3",rsi0:"250",rsi1:"350",pat:"6",tn:"baiduCustNativeAD",rss1:"#FFFFFF",conBW:"1",adp:"1",ptt:"0",titFF:"%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91",titFS:"14",rss2:"#000000",titSU:"0",ptbg:"90",piw:"0",pih:"0",ptp:"0"}
Powered by hexo and Theme by Pacman © 2015
程序员头条
(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else
{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
$('#toc.toc-aside').css('display', 'none');
}
});
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
});(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else
{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
$('#toc.toc-aside').css('display', 'none');
}
});
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
});
(document).ready(function(){
var ai = (′.article−content>iframe′),ae=('.article-content>iframe'),
ae = ('.article-content>embed'),
t = ('#toc'),
h =('#toc'),
h = ('article h2')
ah = (′articleh2′),ta=('article h2'),
ta = ('#toc.toc-aside'),
o = (′.openaside′),c=('.openaside'),
c = ('.closeaside');
if(ai.length>0){
ai.wrap('');
};
if(ae.length>0){
ae.wrap('');
};
if(ah.length==0){
t.css('display','none');
}else{
c.click(function(){
ta.css('display', 'block').addClass('fadeIn');
});
o.click(function(){
ta.css('display', 'none');
});
(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
};
});(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
};
});
(document).ready(function(){
var this=this = ('.share'),
url = this.attr(′data−url′),encodedUrl=encodeURIComponent(url),title=this.attr('data-url'),
encodedUrl = encodeURIComponent(url),
title = this.attr('data-title'),
tsina = $this.attr('data-tsina');
var html = [
'',
'扫描二维码分享到微信朋友圈Loading...Please wait',
'',
'',
'',
'',
'',
''
].join('');
this.append(html);this.append(html);
('.article-share-qrcode').click(function(){
var imgSrc = ('#qrcode-pic').attr('data-src');('#qrcode-pic').attr('data-src');
('#qrcode-pic').attr('src', imgSrc);
('#qrcode-pic').load(function(){('#qrcode-pic').load(function(){
('.qrcode strong').text(' ');
});
});
});
var duoshuoQuery = {short_name:"90159"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = '//static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
相关文章推荐
- 字符串操作——面试题总结
- 面试--问题总结--持续更新--放飞求职梦--2016校招
- 笔试面试错题集1
- 程序员面试必备锦囊,懂了这些工资轻松过万
- 百度2016届网页搜索面试题 队列单链表的实现(队列大小有限制)
- 网友整理的Android面试题集-附网友提供的参考答案
- 女程序员获得成功的技巧
- 要做Java程序员 需要知道那些技术 重点有那些
- 黑马程序员——java复习总结——其他类和IO流
- 黑马程序员--Java集合框架(3)
- Android面试过程描述
- android面试经验谈
- 笔试面试知识点转载
- 黑马程序员--java技术blog---第十一篇:反射
- Android面试题精选,自己收藏下
- 黑马程序员--Java多线程
- 我想问面试官的话(更新中)
- 静态链接的一点小总结(二) 《程序员的自我修养》·笔记
- 多线程经典面试题
- 面试需要注意的十二个得分细节