<?php$access_token='19120281.12eb222.1614fb6d1334221222d66fcd5f258fb';$count_images=90;$cache_time=60;$image_size='thumbnail';/** Output each image with HTML markup */functionechoimage($val,$imagesize){$image=$val["images"][$imagesize]["url"];$link=$val["link"];$tag=md5($link);return"<a href=\"$link\" target=\"_blank\"><img src=\"$image\"/></a>";}/** Getting the Data from the API */functiongetDataFromApi($token,$number){// Instagram API bearbeiten$url="https://api.instagram.com/v1/users/self/media/recent/?access_token=$token&count=$number";$contents=file_get_contents($url);return$contents;}/** Gets the Data from either the Cache or the API */functiongetData($token,$number,$cache_time){$cache_folder="your cache path";if(!is_dir($cache_folder)){if(mkdir($cache_folder,0777)==false){returngetDataFromApi($token,$number);}}$cachefile=$cache_folder."user.cache";if(file_exists($cachefile)&&time()-filemtime($cachefile)<$cache_time){try{$contents=file_get_contents($cachefile);}catch(Exception$e){$contents=getDataFromApi($token,$number);file_put_contents($cachefile,$contents);}}else{$contents=getDataFromApi($token,$number);file_put_contents($cachefile,$contents);}return$contents;}$json=json_decode(getData($access_token,$count_images,$cache_time),true);echo'<div class="photosdiv">';foreach($json["data"]as$value)echoechoimage($value,$image_size);echo'</div>';?>
现在说一下runtime的负面影响:
1. 关于执行效率问题。 “静态语言执行效率要比动态语言高”,这句没错。因为一部分cpu计算损耗在了runtime过程中。而静态语言生成的机器指令更简洁。正因为知道这个原因,所以开发语言的人付出很大一部分努力为了保持runtime小巧上。所以objecitve-c是c的超集+一个小巧的runtime环境。 但是,换句话说,从算法角度考虑,这点复杂度不算差别的,Big O notation结果不会有差别。( It’s not log(n) vs n2 )
2. 另外一个就是安全性。动态语言由于运行时环境的需求,会保留一些源码级别的程序结构。这样就给破解带来的方便之门。一个现成的说明就是,java,大家都知道java运行在jre上面。这就是典型的runtime例子。它的执行文件.class全部可以反编译回近似源代码。所以这里的额外提示就是如果你需要写和安全有关的代码,离objc远点,直接用c去。
简单理解:“Runtime is everything between your each function call.”
NSThread是Mac OS 10.0后发布的多线程API较为高层,但是缺乏灵活性,而且和pthread相比效率低下。
Grand Central Dispatch 是10.6后引入的开源多线程库,它介于pthread和NSThread之间。比NSThread更灵活、小巧,并且不需要像pthread一样考虑很多lock的问题。同时objective-c 2.0发布的新语法特性之一blocks,也正是根据Grand Central Dispatch需求推出的。
所以在你写多线程代码或者阅读多线程代码时候,心理要先明确使用哪种技术。
2. thread和Reference Counting内存管理造成的问题。
线程里面的方法都要放到NSAutoreleasePool里面吗?
这类问题很常见,迷惑的原因是不明白 NSAutoreleasePool 到底是干什么用的。NSAutoreleasePool跟thread其实关系并不显著,它提供一个临时内存管理空间,好比一个沙箱,确保不会有不当的内存分配泄露出来,在这个空间内新分配的对象要向这个pool做一下注册告诉:“pool,我新分配一块空间了”。当pool drain掉或者release,它里面分配过的内存同样释放掉。可见和thread没有很大关系。但是,我们阅读代码的时候经常会看到,新开线程的函数内总是以NSAutoreleasePool开始结束。这又是为什么呢!? 因为thread内恰好是最适合需要它的地方! 线程函数应该计算量大,时间长(supposed to be heavy)。在线程里面可能会有大量对象生成,这时使用autoreleasepool管理更简洁。所以这里的答案是,不一定非要在线程里放NSAutoreleasePool,相对的在cocoa环境下任意地方都可以使用NSAutoreleasePool。如果你在线程内不使用NSAutoreleasePool,要记得在内部alloc和relase配对出现保证没有内存泄露。
-(void)myThread:(id)sender{NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];while(TRUE){//do some jobs//break in some conditionusleep(10000);[pooldrain];}[poolrelease];}
NSMutableArray*targetQueue;NSMutableArray*actionQueue;-(void)myThread:(id)sender{NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];while(TRUE){//do some jobs//break in some conditionintn=[targetQueuecount];assert(n==[actionQueuecount]);for(inti=0;i<n;i++){idtarget=[targetQueueobjectAtIndex:i];SELaction=NSSelectorFromString([actionQueueobjectAtIndex:i]);if([targetrespondsToSelector:action]){[targetperformSelector:actionwithObject:nil];}}usleep(10000);[pooldrain];}[poolrelease];}
注意,这里没有做线程安全处理,记住Mutable container is not thread safe.
这个简单的扩展,让我们看到了如何利用runtime能力让线程灵活起来。当我们从另外线程向targetQueue和actionQueue同时加入对象和方法时候,这个线程函数就有了执行一个额外代码的能力。
@interfaceMyNSThread : NSObject{MyNSRunloop*runloop;}-(void)main:(id)sender;@end@implementationMyNSThread-(void)main:(id)sender{NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];while(TRUE){//do some jobs//break in some condition[runloopexecuteOnce];usleep(10000);[pooldrain];}[poolrelease];}@end
Category methods should not override existing methods (class or instance).
Two different categories implementing the same method results in undefined behavior