不务正业之OC(三)retain与release

当我们打开ARC自动引用计数时,retainCount不可用,那就关闭吧

1

2

Person.h

#import <Foundation/Foundation.h>
 
@interface Person : NSObject
@end

Person.m

#import "Person.h"
 
@implementation Person
//定义dealloc方法,当对象引用计数为0时,会被调用
- (void)dealloc{
    NSLog(@"Person is dealloc!");
    [super dealloc];
}
@end

main.m

#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        //alloc 引用计数加1;retainCount方法返回对象引用计数数
        Person *person1 = [[Person alloc] init]; //1
        NSLog(@"person1:%lu",(unsigned long)[person1 retainCount]);
 
        [person1 retain];//2
        NSLog(@"person1:%lu",(unsigned long)[person1 retainCount]);
 
        [person1 release];//1
        NSLog(@"person1:%lu",(unsigned long)[person1 retainCount]);
 
        [person1 release];//0,调用dealloc
    }
    return 0;
}

结果:

2014-04-27 17:16:48.041 Person[10196:303] person1:1
2014-04-27 17:16:48.043 Person[10196:303] person1:2
2014-04-27 17:16:48.043 Person[10196:303] person1:1
2014-04-27 17:16:48.043 Person[10196:303] Person is dealloc!

不务正业之OC(三)扩展

不像C++有关键词private来申明私用方法(实例变量除外),OC没有关键词来申明是私有方法,当我们可以用类的extension来实现私有方法

1、Person.m实现在文件中@interface…@end来申明私有方法(头文件中未申明),那这个方法不能在其他对象中调用

#import "Person.h"
 
@interface Person()  //括号里没有写东西,如果写了就是类别,不写就是extension
- (void) whereLive;
@end
 
@implementation Person
@synthesize name;
@synthesize age;
 
- (void) whereLive{
    NSLog(@"living in xiaoshan");
}
 
- (NSString *) description{
    NSString *desc;
    desc = [[NSString alloc] initWithFormat:@"Person:name is %@,age is %ld", self.name,(long)self.age ];
    return desc;
}
@end

2、到main函数中来调用

#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.name = @"liyi(my son)";
        person.age = 1;
        NSLog(@"%@",person);
        [person whereLive];
    }
    return 0;
}

Xcode会报whereLive方法未定义,找不到

其实我们可以间接方式来进行私有方法,修改代码
Person.h:

#import <Foundation/Foundation.h>
 
@interface Person : NSObject
{
    NSString *name;
    NSInteger age;
}
@property (copy) NSString* name;
@property  NSInteger age;
//定义可以访问私有方法的方法accessPrivate
- (void) accessPrivate;
@end

Person.m 定义extension whereLive

#import "Person.h"
 
@interface Person()  //括号里没有写东西,如果写了就是类别,不写就是extension
- (void) whereLive;
@end
 
@implementation Person
@synthesize name;
@synthesize age;
 
- (void) whereLive{
    NSLog(@"living in xiaoshan");
}
 
- (void) accessPrivate{
    [self whereLive];
}
 
- (NSString *) description{
    NSString *desc;
    desc = [[NSString alloc] initWithFormat:@"Person:name is %@,age is %ld", self.name,(long)self.age ];
    return desc;
}
@end

main函数

#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person.name = @"liyi(my son)";
        person.age = 1;
        NSLog(@"%@",person);
        //不直接访问whereLive
        [person accessPrivate];
    }
    return 0;
}

结果:

2014-04-27 16:43:49.610 Person[10054:303] Person:name is liyi(my son),age is 1
2014-04-27 16:43:49.612 Person[10054:303] living in xiaoshan

下节介绍内存管理,enjoy it!

不务正业之OC(二)点语法

大家不要和NSPredicate的点来指定路径搞混了,NSPredicate非常强大,基本把数据库的sql语法实现一遍,特别在遍历一个集合对象时,非常方便,一行代码搞定全部功能。
这边点语法指属性访问,所谓无码无真相,go

Person类实现:

#import "Person.h"
@implementation Person
@synthesize name;
@synthesize age;
 
- (NSString *) description{
    NSString *desc;
    desc = [[NSString alloc] initWithFormat:@"Person:name is %@,age is %ld", self.name,(long)self.age ];
    return desc;
}
@end

main方法:

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Person *person = [[Person alloc] init]; //这里为啥不[person release]?就因为自动释放噢
        person.name = @"liyi(my son)";
        person.age = 1;
        NSLog(@"%@",person);
    }
    return 0;
}

运行结果:

2014-04-27 16:06:06.526 Person[9841:303] Person:name is liyi(my son),age is 1
Program ended with exit code: 0

不务正业之OC(一)

有空就学学吧,写写APP吧,以后我会多写写OC相关文章,今天来个入门级的,其实也不算入门了,牵涉到@property和@synthesize使用,大家就随便看看吧.
Xcode4.3版本及以上不需要定义@synthesize,Xcode帮你搞定了

1、首先我们来定义一个Person类

类定义:

//
//  Person.h
//  Person
//
//  Created by Li Jie on 14-4-27.
//  Copyright (c) 2014年 stronghearted. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
//定义Person类继承NSObject,多说一句,OC不支持多重继承,和C++不一样,但OC可以通过类别来实现多重继承的功能
@interface Person : NSObject
{   
    //定义name、age两个实例变量,记住,类别是不支持实例变量的,只支持方法扩展
    NSString *name;
    NSInteger age;
}
//property就类似JAVA中我们经常用的set方法,叫做设置方法。大家还看到copy关键词,这样关键词还有很多:nonatimic,retain,assign,readonly,readwrite;copy创建新对象,引用计数+1,释放旧对象(说不完全,以后展开讲)
//@synthesize就类似JAVA中我们用的get方法,叫做访问方法
@property (copy) NSString* name;
@property  NSInteger age;
@end

类实现:

//
//  Person.m
//  Person
//
//  Created by Li Jie on 14-4-27.
//  Copyright (c) 2014年 stronghearted. All rights reserved.
//
 
#import "Person.h"
 
@implementation Person
@synthesize name;
@synthesize age;
//重写NSOjbect的init方法,调用本对象的initWithPersion来初始化实例变量,返回对象本身
- (id) init
{
    if (self = [self initWithPerson:@"luoxuan" setAge:31]) {
    }
 
    return (self);
 
}
 
- (id) initWithPerson: (NSString *) _name
             setAge: (NSInteger) _age
{
    if (self = [super init]) {
        name = _name;
        age = _age;
    }
    return (self);
}
//当NSLOG使用对象时,变会自动调用description方法,这边我们也写重写了descrition方法
- (NSString *) description{
    NSString *desc;
    desc = [[NSString alloc] initWithFormat:@"Person:name is %@,age is %ld", self.name,(long)self.age ];
    return desc;
}
@end

2、学过C的同学者知道,调用都是从main作为入口
main函数定义

//
//  main.m
//  Person
//
//  Created by Li Jie on 14-4-27.
//  Copyright (c) 2014年 stronghearted. All rights reserved.
//
 
#import <Foundation/Foundation.h>
//引入头文件
#import "Person.h"
 
int main(int argc, const char * argv[])
{
    //autorelaesepool  自动释放池,当我们alloc、new、copy、retain创建对象时,引用计数会加1,如果没有release,那就出现memory leak哦
    @autoreleasepool { 
        //创建person对象,并调用初始化方法
        Person *person = [[Person alloc] init];
        //打印person对象
        NSLog(@"%@",person);
    }
    return 0;
}

运行结果:

2014-04-27 15:02:20.375 Person[9104:303] Person:name is luoxuan,age is 31
Program ended with exit code: 0

pt-query-digest的一个问题

昨天有同学问,用pt-query-digest分析后,发现排在最前面都是ADMIN开头的语句,真正的语句却没有真实反映在报表中

$ sudo pt-query-digest --type genlog /tmp/general.log  --order-by Query_time:cnt --limit 3
 
# Profile
# Rank Query ID           Response time Calls R/Call V/M   Item
# ==== ================== ============= ===== ====== ===== =============
#    1 0x440061F2EB7A7639  0.0000  0.0% 53390 0.0000  0.00 ADMIN CLOSE
#    2 0x99AA0165670CE848  0.0000  0.0% 53389 0.0000  0.00 ADMIN PREPARE
#    3 0x1228F184663C8627  0.0000  0.0% 53386 0.0000  0.00 ADMIN EXECUTE
# MISC 0xMISC              0.0000  0.0%  5042 0.0000   0.0 <42 ITEMS>

首先要知道这些语句是因为JAVA使用preparestatment引起,打开general.log发现类似语句:

11637701 Prepare select * from t  
 11637701 Execute select * from t
 11637701 Close stmt

pt-query-digest没有很好处理prepare及execute后面语句,导致真正的sql没有展示出来。
想到把Execute改成Query,把其余的ADMIN过滤掉,那就是一份正确的报告了。

$sed -i 's/Execute/Query/g' /tmp/general.log 
$ sudo pt-query-digest --type genlog /tmp/general.log --filter '$event->{fingerprint} !~ m/^admin/i' --order-by Query_time:cnt --limit 3
# Profile
# Rank Query ID           Response time Calls R/Call V/M   Item
# ==== ================== ============= ===== ====== ===== ===============
#    1 0x2DAF846CC781D91A  0.0000  0.0% 14855 0.0000  0.00 SELECT t?
#    2 0x7164FF6E647C5863  0.0000  0.0% 11604 0.0000  0.00 SELECT t2?
#    3 0x6576B004C40147B5  0.0000  0.0%  4582 0.0000  0.00 SELECT t3

可以看到真正的sql出来

细心同学会发现ADMIN CLOSE、ADMIN PREPARE、ADMIN EXECUTE的值几乎都是一样,理论上应该是相同。