RSS

Category Archives: iOS

iOS中使用代码模拟内存警告

做iOS开发在模拟器上可以通过 Hardware -> Simulate Memory Warning 模拟内存警告,当我们使用真机的时候,或者说想给测试的同事也提供这样功能的时候,那我们就需要写程序,通过代码来实现了。

代码很简单,就一行:

[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];

但是请注意,最好只在测试的时候使用,发布到App Store的时候不要将上面的代码编译进去,使用这种没有文档化的方法有可能导致审核不通过,或者根本无法上传。


 
添加留言

Posted by on 十一月 5, 2012 in iOS

 

Tags: , ,

ARC forbids explicit message send of ‘retain’ ‘release’ ‘autorelease’ ‘dealloc’ ‘retainCount’

之前写了一篇ARC forbids explicit message send of ‘dealloc’的解决方案 ,看到很多朋友不是搜索dealloc而是搜索retain, release过来的,这里一起解答一下。

ARC forbids explicit message send of ….从字面意思上也很好理解,ARC禁止显式(直接)发送retain, release, dealloc…等消息。其实就是使用ARC之后,不允许直接调用retain, release, autorelease, dealloc, retainCount这些方法了,编译器会在合适的地方将这些代码添加进去,解决这样的问题只需要删除与手动管理内存相关的代码(一般就是报错的代码)即可。

习惯了手动管理内存的朋友可以选择禁用ARC,如果想体验ARC带来的编码上的便捷,可以先看一下下面列出的文档:

https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

 

 
添加留言

Posted by on 四月 9, 2012 in iOS

 

Tags: , , , ,

苹果禁止访问UDID(uniqueIdentifier)的替代方案

最近看到新闻,苹果已经开始拒绝访问了UDID的App提交到App Store了,轰轰烈烈的用户隐私保护运动似乎初见成效。但是程序员们似乎要郁闷了,没有了UDID,我们该如何追踪用户呢?

长期以来,iOS程序员们使用UIDevice.uniqueIdentifier作为追踪单一用户(设备)的标识。在iOS5.0 SDK中,我们可以看到uniqueIdentifier已经被注明为Deprecated的了,但是官方文档也提供了建议的替代方案,也就是本文的第一种替代方案。

方案一:
使用UUID,根据官方文档的说法:

Do not use the uniqueIdentifier property. To create a unique identifier specific to your app, you can call the CFUUIDCreate function to create a UUID, and write it to the defaults database using the NSUserDefaults class.

我们应该使用CFUUIDCreate来创建一个UUID作为该用户(设备)在本应用的唯一标识,并且结合NSUserDefaults在第一次创建之后,一直使用该该UUID。稍后给出代码链接…

方案二:
使用MAC地址(网卡物理地址)

参考链接:http://iphonedevelopertips.com/device/determine-mac-address.html

但是使用MAC地址与使用uniqueIdentifier没有本质区别,还是违背了保护用户隐私的初衷,并且苹果未来完全可以采取相同的措施。

方案三:
使用第三方的服务,例如OpenFeint宣布的OFUIDOpenUDID,或者只允许注册会员使用,结合会员系统追踪用户。

 
添加留言

Posted by on 三月 28, 2012 in iOS

 

Tags: , , , ,

UITextView使用 sizeWithFont:constrainedToSize:lineBreakMode:计算自适应文本高度

前不久QA报了个文字显示不全的bug,我看了下代码,发现是计算高度出了问题。之前的同事在UITableViewCell中使用了UITextView,但是计算高度时使用了和UILabel相同的的方法。

其实UITextView在上下左右分别有一个8px的padding,当使用[NSString sizeWithFont:constrainedToSize:lineBreakMode:]时,需要将UITextView.contentSize.width减去16像素(左右的padding 2 x 8px)。同时返回的高度中再加上16像素(上下的padding),这样得到的才是UITextView真正适应内容的高度。

示例代码如下:

+ (float) heightForTextView: (UITextView *)textView WithText: (NSString *) strText{
    float fPadding = 16.0; // 8.0px x 2
    CGSize constraint = CGSizeMake(textView.contentSize.width - fPadding, CGFLOAT_MAX);

    CGSize size = [strText sizeWithFont: textView.font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    float fHeight = size.height + 16.0;

    return fHeight;
}
 
2 Comments

Posted by on 三月 21, 2012 in iOS

 

Tags: , , ,

Xcode4/iOS5调试UncaughtException崩溃First throw call stack不打印方法名的解决方案

最近连接iOS5.0.1真机调试的的时候,发现UncaughtException导致crash之后*** First throw call stack:后面没有打印可读的调用堆栈,以前崩溃之后会显示详细的调用的方法名等信息,但是现在都是一堆内存地址0x…..0x…..。

我起初也不知道怎么回事,之前似乎也没碰到过。谷歌了一下,看到了一篇文章(http://stackoverflow.com/questions/7841610/xcode-4-2-debug-doesnt-symbolicate-stack-call)讲貌似是iOS5.0开始做了某些修改,导致不能打印方法名了。但是也有补救措施:

自己定义一个方法:

static void uncaughtExceptionHandler(NSException *exception) {

NSLog(@”CRASH: %@”, exception);

NSLog(@”Stack Trace: %@”, [exception callStackSymbols]);

// Internal error reporting

}

然后在程序初始化的时候调用(比方说放到- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 里面的第一行):

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

 
添加留言

Posted by on 三月 17, 2012 in iOS

 

Tags: , , , , ,

ARC forbids explicit message send of ‘dealloc’的解决方案

在iOS SDK 5.0中使用ARC之后,有些东西咱们还是得在对象销毁的时候做,比如说注销Observer什么的,这个时候还是得重写dealloc方法。但是调用[super dealloc]时系统会提示ARC forbids explicit message send of ‘dealloc’,怎么办呢?

根据苹果官方文档(https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html)的精神,我们无需在重写的dealloc中添加[super dealloc],因为sdk在编译的时候会自己添加上去。

官方文档相关描述如下:

You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn’t compiled using ARC.

Custom dealloc methods in ARC do not require a call to [super dealloc] (it actually results in a compiler error). The chaining to super is automated and enforced by the compiler.

 
添加留言

Posted by on 三月 13, 2012 in iOS