设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

盘点一些iOS开发技巧:Swift和Objective-C

2015-1-15 11:04| 发布者: joejoe0332| 查看: 2484| 评论: 0|原作者: CocoaChina|来自: CocoaChina

摘要: 对苹果开发者来讲,2014年是令人难以置信的一年。在这短短的一年中发生了如此多的变化:在充满吸引力的Swift面前,我们几乎忘了之前是如何痴迷OC;以及充满想象力的iOS8和WatchKit,难以想象还有什么API能与之相比。 ...

保护SDK头文件

如果你用dmg安装Xcode,那么看看这篇Joar Wingfors的文章,它讲述了如何通过保留所有权来避免SDK头文件被意外修改:

  1. $ sudo ditto /Volumes/Xcode/Xcode.app /Applications/Xcode.app  

任意类型的实例变量检测

为了达到逆向处理的目的,查询对象的实例变量是一个常见可靠的途径。通常调用对象valueForKey:方法就能达到这一目的,除了少数重写了类方法+accessInstanceVariablesDirectly的类屏蔽了该操作。

下面是一个例子:当实例变量有一个为任意类型的属性时,上述提到的操作无效

这是iOS6.1 SDK中MediaPlayer 框架的一段引用:

  1. @interface MPMoviePlayerController : NSObject {  
  2.     void *_internal;    // 4 = 0x4  
  3.     BOOL _readyForDisplay;  // 8 = 0x8  
  4. }  
因为 id internal=[moviePlayerController valueForKey:@”internal”] 无效,下面有一个笨办法来取得这个变量:
  1. id internal = *((const id*)(void*)((uintptr_t)moviePlayerController + sizeof(Class)));  

注意!不要随意调用这段代码,因为ivar的布局可能改变(指针偏移量计算可能出错)。仅在逆向工程中使用!

NSDateFormatter +dateFormatFromTemplate:options:locale:

友情提示:假如你调用[NSDateFormatter setDateFormat],而没有调用[NSDateFormatter dateFormatFromTemplate:options:local:],n那么很可能出错。

苹果文档:

  1. + (NSString *)dateFormatFromTemplate:(NSString *)template  
  2.                              options:(NSUInteger)opts  
  3.                               locale:(NSLocale *)locale  

不同地区有不同的日期格式。使用这个方法的目的:得到指定地区指定日期字段的一个合适的格式(通常你可以通过currentLocal查看当前所属地区)

下面这个例子给我们表现了英式英语和美式英语不同的日期格式:

  1. NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];  
  2. NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];  
  3.    
  4. NSString *dateFormat;  
  5. NSString *dateComponents = @"yMMMMd";  
  6.    
  7. dateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:usLocale];  
  8. NSLog(@"Date format for %@: %@",  
  9.     [usLocale displayNameForKey:NSLocaleIdentifier value:[usLocale localeIdentifier]], dateFormat);  
  10.    
  11. dateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:gbLocale];  
  12. NSLog(@"Date format for %@: %@",  
  13.     [gbLocale displayNameForKey:NSLocaleIdentifier value:[gbLocale localeIdentifier]], dateFormat);  
  14.    
  15. // Output:  
  16. // Date format for English (United States): MMMM d, y  
  17. // Date format for English (United Kingdom): d MMMM y  

通过调试获取内部常量

近期,Matthias Tretter在Twitter上问到:

有人知道在iOS8里modal viewController presentation的默认动画时间和跳转方式吗?

我们在UIKit的类库中发现了这样一个函数:[UITransitionView defaultDurationForTransition:],并在这个方法的位置加一个断点:

  1. (lldb) br set -n "+[UITransitionView defaultDurationForTransition:]"  
模态显示一个viewController,就会停在这个断点,输入finish执行该方法:
  1. (lldb)finish  
在defaultDurationForTransition:被执行时,你就能读到结果(在xmm0寄存器里)
  1. (lldb) register read xmm0 --format float64  
  2.     xmm0 = {0.4 0}  
回复:默认动画时间0.4s

DIY 弱关联对象

不幸的是,关联对象OBJC_ASSOCIATION_ASSIGN策略不支持引用计数为0的弱引用。幸运的是,你可以很容易实现它,你仅仅需要一个简单的类,并在这个类里弱引用一个对象:

  1. @interface WeakObjectContainter : NSObject  
  2. @property (nonatomic, readonly, weak) id object;  
  3. @end  
  4. @implementation WeakObjectContainter  
  5. - (instancetype)initWithObject:(id)object {  
  6.     self = [super init];  
  7.     if (!self) {  
  8.         return nil;  
  9.     }  
  10.     self.object = object;  
  11.     return self;  
  12. }  
  13. @end  
然后,通过OBJC_ASSOCIATION_RETAIN(_NONATOMIC)关联WeakObjectContainter:
  1. objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainter alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
用object属性指向这个所需的引用计数为0的弱引用对象。
  1. id object = [objc_getAssociatedObject(self, &MyKey) object];  


英文文章来源:NSHipster,译文出自:CocoaChina


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部