当前位置:  编程技术>移动开发
本页文章导读:
    ▪Titanium的常见异常和对策        Titanium的常见错误和对策 本文会不断更新中![ERROR] Timed out waiting for emulator to be ready, you may need to close the emulator and try again-----关闭Titanium后再启动[ERROR] Script Error = Result of expression 'Titanium.Databa.........
    ▪ (转载)objective-C: NSString应当用initWithFormat? 还是 stringWithFormat        (转载)objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?   objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?     今天在看书上的一段代码时,发现NSString实例化时,有时用的是in.........
    ▪ (转载)objective-C 的内存储器管理之-自动释放池(autorelease pool)       (转载)objective-C 的内存管理之-自动释放池(autorelease pool) objective-C 的内存管理之-自动释放池(autorelease pool)     如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,.........

[1]Titanium的常见异常和对策
    来源: 互联网  发布时间: 2014-02-18
Titanium的常见错误和对策
本文会不断更新中!

[ERROR] Timed out waiting for emulator to be ready, you may need to close the emulator and try again
-----关闭Titanium后再启动

[ERROR] Script Error = Result of expression 'Titanium.Database' [undefined] is not an object. at app.js (line 1).
-----Clean工程后再启动

[ERROR] Error generating R.java from manifest
-----修正Application Id,必须符合FQDN(Fully Qualified Domain Name, 含义是完整的域名),不能有非字符。(Test -> com.example.test)。
     appid中不能包含appcelerator,titanium等官方相关的词语。

[ERROR] Exception occured while building Android project:
[ERROR] Traceback (most recent call last):
・・・・・・・・・・
[ERROR] UnicodeDecodeError: 'utf8' codec can't decode byte 0x82 in position 142: unexpected code type
-----把文件的编码改为"UTF-8"

[ERROR] Failed installing com.appcelerator.kitchensink: pkg: /data/local/tmp/app.apk
[TRACE] Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY]
-----更新SDK版本(建议2.2以上),选择Google APIs

[ERROR] ....../strings.xml:3: error: Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute?
-----把String.xml中的“%d + %d = %d”改为“%1$d + %2$d = %3$d”

[ERROR] JDK version 'javac' is not recognized as an internal or external command
-----把%JAVA_HOME%\bin放入path环境变量中

[ERROR]Code Sign error: The identity ‘iPhone Developer: ‘ doesn’t match any valid certificate/private key pair in the default
-----provisioning profile做的有问题,iOS Provisioning Portal中作成profile时选择Development而不是Distribution

[ERROR] Analytics error sending request: The request timed out
[ERROR] Will re-queue analytics
-----删除build/iphone再试

[TRACE] E/TiHttpClient( 1151): java.net.UnknownHostException: Host is unresolved: xxxxxxx
-----启动emulator时加参数'-dns-server 8.8.8.8'

[DEBUG] D:\android-sdk-windows\tools\emulator.exe -avd titanium_5_HVGA -port 5560 -sdcard "C:\Documents and Settings\RenSanNing\.titanium\titanium_5_HVGA.sdcard" -logcat *:d,* -no-boot-anim -partition-size 128
invalid command-line parameter: C:\Documents.
Hint: use '@foo' to launch a virtual device named 'foo'.
please use -help for more information
[DEBUG] signal caught: 3
[DEBUG] calling emulator kill on 13360
ERROR: The process "13360" not found.
-----通过以下命令在外部启动模拟器后,再在Titanium Studio中启动一次即可。
emulator.exe -avd titanium_5_HVGA -port 5560

"Could not locate the Android SDK at a given path" in Preferences
-----下载Android 2.1 API 7 或 Google APIs Android API 7 打开「Window→Preferences→Aptana Studio→Titanium」设置Android SDK。
关于这个问题Titanium Compatibility Matrix中说的很清楚,如图:


Distribute Android marketplace为APK签名是出错
[ERROR] Unable to open 'F:\_workspace_titanium\_test_mobile2\_sign\_test_mobile2.apk' as zip archive
[ERROR] System Error while compiling Android classes.dex
-----确认密码,别名等信息是否跟keystore一致,具体步骤参考通过Titanium Studio为Android APK签名

[ERROR] JDK version 1.7.0_02 detected, but 1.6 is required
-----安装JDK1.6版本,具体可以查看源码C:\Documents and Settings\$user_name$\Application Data\Titanium\mobilesdk\win32\1.8.2\android\prereq.py





1 楼 annqilee 2012-03-23  
我在distribute成android的时候,先在keytools里生成了keystore,然后distribute Android marketplace,这个时候报了错误,知道怎么解决吗?

错误:
[ERROR] Unable to open 'F:\_workspace_titanium\_test_mobile2\_sign\_test_mobile2.apk' as zip archive
[ERROR] System Error while compiling Android classes.dex
2 楼 rensanning 2012-03-23  
检查一下你的keystore alias和distribute时的是否一致。
3 楼 rensanning 2012-03-23  
Titanium默认的keystore试试好不好用:
path:$TitaniumSDK_HOME$\mobilesdk\win32\1.8.2\android\dev_keystore
password:tirocks
alias:tidev

TitaniumSDK_HOME默认是:C:\Documents and Settings\#user_name#\Application Data\Titanium\当然也可以指定到其他目录下。
4 楼 annqilee 2012-03-23  
还是不可以

    
[2] (转载)objective-C: NSString应当用initWithFormat? 还是 stringWithFormat
    来源: 互联网  发布时间: 2014-02-18
(转载)objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?

 

objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?

 

 

今天在看书上的一段代码时,发现NSString实例化时,有时用的是initWithFormat方法,有时用的是stringWithFormat,到底应该如何选择呢?

区别:

1、 initWithFormat是实例方法

只能通过 NSString* str = [[NSString alloc] initWithFormat:@"%@",@"Hello World"] 调用,但是必须手动release来释放内存资源

2、 stringWithFormat是类方法

可以直接用 NSString* str = [NSString stringWithFormat:@"%@",@"Hello World"] 调用,内存管理上是autorelease的,不用手动显式release


另外国外有个贴子对此有专门讨论(http://www.iphonedevsdk.com/forum/iphone-sdk-development/29249-nsstring-initwithformat-vs-stringwithformat.html )

而且提出了一个常见错误:

label.text = [[NSString alloc] initWithFormat:@"%@",@"abc"];

最后在dealloc中将label给release掉

但是仍然会发生内存泄漏!

原因在于:用label.text = ...时,实际是隐式调用的label的setText方法,这会retain label内部的字符串变量text(哪怕这个字符串的内容 跟传进来的字符串内容相同 ,但系统仍然当成二个不同 的字符串对象),所以最后release label时,实际上只释放了label内部的text字符串,但是最初用initWithFormat生成的字符串并未释放,最终造成了泄漏。

解决办法有二个:

1、

NSString * str = [[NSString alloc] initWithFormat:@"%@",@"abc"];

label.text = str;

[str release]

最后在dealloc中再[label release]

2、

label.text = [NSString stringWithFormat:@"%@",@"abc"];

然后剩下的事情交给NSAutoreleasePool

最后,如果你不确定你的代码是否有内存泄漏问题,可以用Xcode中的Build-->Build And Analyze 做初步的检查.

 


 

作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 


    
[3] (转载)objective-C 的内存储器管理之-自动释放池(autorelease pool)
    来源: 互联网  发布时间: 2014-02-18
(转载)objective-C 的内存管理之-自动释放池(autorelease pool)
objective-C 的内存管理之-自动释放池(autorelease pool)

 

 

如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣。但是有些时候,想知道某个对象在什么时候不再使用并不那么容易。如果下面的代码,看上去非常简单:

Sample.h类接口部分

#import < Foundation / Foundation.h >
@interface Sample : NSObject {

}

-(NSString*) toString;

@end

Sample.m 类实现部分

#import "Sample.h"

@implementation Sample


-(NSString*) toString
{
	NSString* str = [[NSString alloc] initWithFormat:@"This is %@ class",@"Sample"];
	return str;
}
@end

在main函数中调用

#import <Foundation/Foundation.h>
#import "Sample.h"

int main (int argc, const char * argv[]) {	
	
	Sample *s = [Sample new];
	NSLog(@"%@",[s toString]);
	[s release];
	
    return 0;
	
    
}

不知道您是否意识到这段代码有内存泄漏 问题,因为Sample.m的toString方法生成了一个NSString类的实例,但是main函数最后只释放了Sample的实例s,却并未释放这个NSString类的字符串实例!

要纠正这个错误,main函数应该改成:

int main (int argc, const char * argv[]) {	
	
	Sample *s = [Sample new];
	NSString* str = [s toString];
	NSLog(@"%@",str);
	[str release];//手动释放NSString字符串实例
	[s release];
	
    return 0;	
    
}

这种隐藏的错误很容易发生,也容易被忽视。为此obj-c 引用了自动释放池(autorelease pool),每次用xcode创建项目时,可能大家已经注意到了有类似下面的代码模板:

int main (int argc, const char * argv[]) {	
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	//insert code here...
	NSLog(@"Hello,World!");
	
	[pool drain];	
    return 0;	
    
}

即:xcode为开发者写的代码外层包了一层NSAutoreleasePool 。这个池(pool)类似数据结构中的堆栈(Stack),相当于一个容器,每次对象调用autorelease方法时(obj-c中的正式说法应该是:对象发送autorelease消息),对象的引用计数并不 真正变化 , 而是向pool中添加一条记录,记下对象的这种要求。最后当pool发送drain或release消息时,池中的所有对象的这种要求一一被执行 (即:pool被销毁前,会通知池中的所有对象,全部发送release消息真正将引用计数减少,如果对象之前有发送过autorelease消息)

下面看一下基本的使用,先给Sample添加一个属性int型的flag(用于在销毁时看到是哪一个实例正在被销毁),同时重写dealloc()以便在释放时能输出一些信息

Sample.h

#import <Foundation/Foundation.h>

@interface Sample : NSObject {	

}

-(NSString*) toString;

//增加一个int型的属性flag
@property int flag;

@end

Sample.m

#import "Sample.h"

@implementation Sample

//自动生成属性flag的setter与getter方法
@synthesize flag;

-(NSString*) toString
{
	NSString* str = [[NSString alloc] initWithFormat:@"This is Sample%d",flag];
	return str;
}


-(void)dealloc
{
	NSLog(@"Sample %d is going to die.",flag);
	[super dealloc];
}
@end

使用自动释放池后的main函数

#import <Foundation/Foundation.h>
#import "Sample.h"

int main (int argc, const char * argv[]) {	
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	Sample *s1 = [Sample new];
	Sample *s2 = [Sample new];
	
	s1.flag=1;
	s2.flag=2;
	
	[s1 autorelease];
	[s2 autorelease];
	
	
	[pool drain];	
    return 0;	
    
}

运行结果为:

2011-02-24 13:28:09.759 MemoryManage[282:a0f] Sample 2 is going to die.
2011-02-24 13:28:09.769 MemoryManage[282:a0f] Sample 1 is going to die.

从结果上看,pool是后进先出的,即:最后autorelease的最先释放(符合stack数据结构的特征)。再回到前面提到的toString方法中内存泄漏的问题,明白pool的基本原理后,只要把return str 换成retrun [str autorelease] 就行了,即把该字符串在池中登记,这样当[pool drain]时,所有登记的对象,将自动调用release方法,从而得到释放。

自动释放池从功能上可以理解为一种延时释放 技术:即通过发送autorelease消息,向自动释放池登记,表明自己将来会在pool销毁时,一并发送release消息销毁自己。

最后提几点注意事项 :

1、 NSAutoreleasePool的实例pool本身也是一个 对象,同样需要释放,所以最后也同样需要[pool release]或[pool drain],也正是这一行代码,才会将池中的所有对象同时释放。--注:drain仅适用于max os高版本,低版本不适用,而release通用,其它并无太大差别

2、 pool在release时,仅仅只是简单的让所有池中的对象都 发送release而已,并无其它玄机。(即:让池中所有对象的引用计数减1) 所以,如果你在之前用代码强制retain了某对象的引用计数,即使pool被release了,池中的对象仍然有可能因为引用计数仍大于1,而未被销 毁。比如下面的代码:

#import <Foundation/Foundation.h>
#import "Sample.h"

int main (int argc, const char * argv[]) {	
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	Sample *s1 = [Sample new];//retainCount=1
	Sample *s2 = [Sample new];//retainCount=1
	
	s1.flag=1;
	s2.flag=2;
	
	NSLog(@"s1.retainCount=%d,s2.retainCount=%d",[s1 retainCount],[s2 retainCount]);
	
	[s1 autorelease];//retainCount仍为1
	
	NSLog(@"s1.retainCount=%d,s2.retainCount=%d",[s1 retainCount],[s2 retainCount]);
	
	[s2 retain];//retainCount=2
	[s2 autorelease];//retainCount仍为2	
	
	NSLog(@"s1.retainCount=%d,s2.retainCount=%d",[s1 retainCount],[s2 retainCount]);	
	
	[pool drain];	
   
	return 0;	
    
}

运行结果:

2011-02-24 13:49:22.558 MemoryManage[461:a0f] s1.retainCount=1,s2.retainCount=1
2011-02-24 13:49:22.566 MemoryManage[461:a0f] s1.retainCount=1,s2.retainCount=1
2011-02-24 13:49:22.567 MemoryManage[461:a0f] s1.retainCount=1,s2.retainCount=2
2011-02-24 13:49:22.578 MemoryManage[461:a0f] Sample 1 is going to die.

因为s2发送了retain消息,从而让其引用计数上升为2,所以最终即使pool释放后,s2仍未销毁。

3、 在iphone/ipad等内存有限的手持设备上,并不建议 使用autorelease,因为说到底这是一种延时释放,如果你的程序一直在跑,代码尚未执行到[pool release]之前,即使有很多对象不再需要了,但它们占用的内存并未真正释放。

4、 不要把大量循环操作放到同一个NSAutoreleasePool之间,道理同上,这样会使池中有大量对象,导致程序在运行时占用较多内存。比如下面这段代码:

int main (int argc, const char * argv[]) {	
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];	
		
	int i;
	
	for	(i=0;i<10000;i++){
		Sample *s = [Sample new];
		s.flag = i;
		NSLog(@"%@",[s toString]);
		[s autorelease];
	}
   
	[pool release];
	return 0;	
    
}

上面的代码运行时,必须等整个循环结束后才开始销毁对象。可以改进为下面这样:

int main (int argc, const char * argv[]) {	
	
	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];	
		
	int i;
	
	for	(i=0;i<10000;i++){
		Sample *s = [Sample new];
		s.flag = i;
		NSLog(@"%@",[s toString]);
		[s autorelease];
		if (i % 100==0)
		{
			[pool release];
			pool = [[NSAutoreleasePool alloc] init];
		}
	}
   
	[pool release];
	return 0;	
    
}

这样每当池子里有100个对象时,就释放一次,这样程序在运行时占用的内存就会少很多

最后从书上抄一段号称Cocoa内存管理的黄金定律:如果我使用了new、alloc或copy方法获得一个对象,则我必须释放(release)或自动释放(autorelease)该对象

作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android显式启动与隐式启动Activity的区别介绍 iis7站长之家
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3