本人博客原文
private final static Handler mainHandler=new Handler(Looper.getMainLooper());private final static HandlerThread business0HandlerThread = new HandlerThread("Business0Handler");private static Handler business0Handler;private final static HandlerThread business1HandlerThread = new HandlerThread("Business1Handler");private static Handler business1Handler;/*该Handler运行在主线程中,因此一些必须放在主线程来处理的事务可以用该Hanlder来处理*/public static Handler getMainHandler() {return mainHandler;}/*该Handler主要用于小事务处理,对于一些耗时但30秒钟能执行完的操作,建议大家放到该Handler来处理*/public static Handler getBusiness0Handler() {if (business0Handler == null) {synchronized(AppUtil.class){if(business0Handler==null) {business0HandlerThread.start();business0Handler = new Handler(business0HandlerThread.getLooper());}}}return business0Handler;}/** 该Handler主要用于大事务处理,它可能会非常繁忙,它也许10分钟或许更久都没有空。*/public static Handler getBusiness1Handler() {if (business1Handler == null) {synchronized(AppUtil.class){if(business1Handler==null) {business1HandlerThread.start();business1Handler = new Handler(business1HandlerThread.getLooper());}}}return business1Handler;}
Runnable r = new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }; getMainHandler().post(r); Runnable r0 = new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }; getBusiness0Handler().post(r0); Runnable r1 = new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }; getBusiness1Handler().post(r1);
发现所有的Handler都被打上了"This Handler class should be static or leaks might occur .."的警告, Google一番后发现了解决方法.
一>, 原因
找到一段E文
Issue: Ensures that Handler classes do not hold on to a reference to an outer class
确保Hanler类不持有外部类的引用
In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the
outer class, declare the Handler as a static nested class with a WeakReference to its outer class.
在Android中, Handler类应是static的, 否则可能会发生泄漏. 程序线程的消息队列的Message也持有对Handler对象的引用. 如果Handler是内部类, 那么(回收内存时)其外部类也会被保留.(使用Handler的Service和Activity就也无法被回收. 这就可能导致内存泄露.) 为了避免泄露其外部类, 可将Handler声明为static并持有其外部类的WeakReference(弱引用).
二>, 解决方法
上面已经指名了一条王道, 将Handler声明为static并持有其外部类的WeakReference(弱引用).
static class MHandler extends Handler { WeakReference<OuterClass> outerClass; MHandler(OuterClass activity) { outerClass = new WeakReference<OuterClass>(activity); } @Override public void handleMessage(android.os.Message msg) { OuterClass theClass = outerClass.get(); switch (msg.what) { case 0: { //使用theClass访问外部类成员和方法 break; } default: { Log.w(TAG, "未知的Handler Message:" + msg.what); } } } }
1.selector:相当于函数指针,oc中函数指针类型为SEL
-(int) add:(int)val;
SEL class_func;
class_func = @selector(add:);
class_func 是当前类方法的指针
[object @selector(add:)] 用于取object对应类中的方法的指针
NSSelectorFromString(方法名字符串),用于根据函数名来取对应函数的指针
反过来也可以:NSStringFromSelector(SEL)
冒号的规则(使用字符串查找的冒号规则也是这样的):
无参数的不需要冒号
-(void) fun;
@selector(fun);
一个参数加一个冒号:
-(void) fun:(int)a;
@selector(fun:);
两个及以上参数,第二个开始,每多一个参数,后面多加一个参数label和冒号
-(void) fun:(int)a andparam2:(int)b;
@selector(fun:andparam2:);
执行:
[self performSelector:@selector(fun:andparam2:) withobject:1 withobject:2]
2.动态识别:
NSObject有一系列动态识别的接口,还有一个class方法返回一个class对象作为参数传给这些接口:
bool bFlag = [square isMemberOf :[Square class]];
isMemberOf:是否是某个类的对象
isKindOf:是否是某个类的或其子孙类的对象
3.NSLog:(使用c++的方式调用)
NSLog(@"字符串第 %d 位为 %c",i,c);
NSLog(@"to = %@",to);
4.SString 与 char* 的区别
NSString是一个objective对象,而char* 是一个字节数组。@+ " 字符串 " 这个符号为objective-c NSString 字符串常量的标准用法,char* 创建的时候 无需添加@
char*c = "xuanyusong";
NSString *temp = @"我是临时字符串";
const char *strTemp = [temp UTF8String];//NSString是unicode,转成utf8字符串
5.bool型真为YES,假为NO(true和false也行,但不建议)
6.数组:
NSArray:创建一个不可变的数组,一旦初始化完毕后这个数组的元素是不可以在动态的添加与删除。只能存NSObject,不能存基本类型(字符串不是基本类型)
mArray = [[NSArray alloc] initWithObjects:@“a”,self,nil];
遍历:
#import
<UIKit/UIKit.h>
#import "MyClass.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//添加我们的测试代码
//创建自定义类
MyClass *myClass = [[MyClass alloc]init];
//创建一个不可变的数组
NSArray *array= [NSArray arrayWithObjects:@"雨松", @"MOMO",@"哇咔咔",myClass,nil];
//得到数组的长度
int count = [array count];
//遍历这个数组
for (int i = 0; i < count; i++) {
NSLog(@"普通的遍历:i = %d 时的数组对象为: %@",i,[array objectAtIndex: i]);
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
或:
#import
<UIKit/UIKit.h>
#import "MyClass.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//添加我们的测试代码
//创建自定义类
MyClass *myClass = [[MyClass alloc]init];
//创建一个不可变的数组
NSArray *array= [NSArray arrayWithObjects:@"雨松", @"MOMO",@"哇咔咔",myClass,nil];
//遍历这个数组
for (NSObject *object in array) {
NSLog(@"快速的遍历数组对象为: %@",object);
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
数组必须以nil结束,指针打印的是地址
NSMutableArray :可变数组
#import <UIKit/UIKit.h>
#import "MyClass.h"
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//添加我们的测试代码
//创建自定义类
MyClass *myClass = [[MyClass alloc]init];
//创建一个可变的数组长度为10
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10];
//向数组中动态的添加对象
[array addObject:@"雨松"];
[array addObject:@"MOMO"];
[array addObject:@"小可爱"];
[array addObject:@"哇咔咔"];
[array addObject:myClass];
for (NSObject * object in array)
{
NSLog(@"输出对象数组:%@", object);
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
NSString *str3 = [NSString stringWithUTF8String:"中国"];//没有加@,说明是char*,默认是UTF-8编码的
8.NSMutableString:可变的字符串
NSMutableString *str = [NSMutableString stringWithString:@"中国"];//有加@,说明是NSString,无需转换
NSMutableString *str2;
str2
= str;
[str insertString:@"深圳" atIndex:0];
//str2也跟着变化了,因为是指向同一个对象的指针
9.字符串跟其他类型之间转换:
NSString *str0 = @"1121";
//把字符串强转成整型
int i = [str0 intValue]; //i值为10,如果是非数组字符串转成数字,转换后的数组为0
10.static变量:
//警告
//static int sCount ;
@interface MyClass : NSObject
{
//错误的写法
//static int sCount;
}
+(void) addCount;
@end
正确的写法是把static变量写在.m文件里:
#import "MyClass.h"
static int sCount = 100;
@implementation MyClass
+(void)addCount
{
sCount ++;
NSLog(@"静态整型变量的值为:%d", sCount);
}
@end
也可以写在方法中,作为局部变量:
+(void)addCount
{
static int sCount = 100;
sCount ++;
NSLog(@"静态整型变量的值为:%d", sCount);
}
不管怎么写,静态变量只初始化一次,就是在程序刚调用起来的时候,所以上面的两个static初始化语句
static int sCount = 100;
都只执行一次,sCount ++; 调用多少次就执行多少次
没有赋初始值时,static int变量默认初始赋值为0
11.字典:NSDictionary (不可变),NSMutableDictionary(可变),同一个词典对象中可以保存多个不同类型的数据,不像Java与C只能保存声明的相同类型的数据
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"niuzai",@"name",@"13225455896",@"number", nil];
注意key值是在value后面的
12.NSSet,NSMutableSet:集合,里面的元素是按哈希算法无序存放的,NSArray NSMutableArray是有序存放的,放在一整块内存中,set的查找效率高(哈希算法)