不务正业之OC(十五)–代理设计模式

什么是代理设计模式:两个对象相互协作,完成共同的目标。
比如:A需要开发一个app,但又不会,把这个需求发到网上去,这时B看到A的需求,B说我能完成这个任务,B接到这个任务并完成后,通知A。

特点:
1、减小对象之间的耦合度
2、无需子类化

代理设计模式按书上例子写一下:Person实例要找房子,但Person实例没有这个能力,那就委托给Agent类去找房子,找到房子后,和Person实例说,我找到房子
Person类、Agent类、FindApartment协议

 
//  Person.h 
 
#import <Foundation/Foundation.h>
#import "FindApartment.h"
 
@interface Person : NSObject
{
@private
    NSString *_name;
    id <FindApartment> delegate;
}
 
@property(nonatomic,copy) NSString *name;
@property(nonatomic,assign) id<FindApartment> delegate;
//初始化Person对象name及委托人(找谁来找房子)
- (id) initWithName:(NSString *)name withDelegate:(id <FindApartment>) delegate;
//Person对象需求
- (void) wantToFindApartment;
 
@end
 
//  Person.m
 
#import "Person.h"
 
@implementation Person
 
@synthesize name = _name;
@synthesize delegate = _delegate;
 
- (id) initWithName:(NSString *)name withDelegate:(id <FindApartment>) delegate{
 
    if (self = [super init]) {
        self.name = name;
        self.delegate = delegate;
    }
    return self;
}
 
- (void) wantToFindApartment{
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(startFindApartment:) userInfo:nil repeats:YES];
}
 
- (void)startFindApartment:(NSTimer *) timer{
    [self.delegate findApartment];
 
}
 
@end
 
//  Agent.h
 
#import <Foundation/Foundation.h>
#import "FindApartment.h"
 
@interface Agent : NSObject<FindApartment>
 
@end
 
//  Agent.m
 
#import "Agent.h"
//委托人需要实现<FindApartment>中定义方法,Agent有这个能力来找房子
@implementation Agent
- (void)findApartment{
    NSLog(@"find");
}
 
@end
 
//  FindApartment.h
 
#import <Foundation/Foundation.h>
//协议定义
@protocol FindApartment <NSObject>
 
- (void)findApartment;
 
@end
 
 
//  main.m
//  Delegate
 
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Agent.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Agent *agent = [[Agent alloc] init];
        //委托给agent来找房子
        Person *jack = [[Person alloc] initWithName:@"jack" withDelegate:agent];
        //调用wantToFindApartment会触发定时器,每隔2s钟调用delegate(这个delegate就是agent)会调用findApartment方法
        [jack wantToFindApartment];
 
        [[NSRunLoop currentRunLoop] run];
 
    }
    return 0;
}

不务正业之OC(十三)–protocol

协议:类似一个类的接口,没有父类,不能定义实例变量;定义方法,需要被另外类实现
使用场合:
1、需要别的类实现方法
2、声明未知类的接口
3、两类之间进行通讯

两关键词
@required
@optional

 
//创建协议
//  MyProtocol.h
 
#import <Foundation/Foundation.h>
 
@protocol MyProtocol <NSObject>
 
@required
- (void) requiredMethod;
 
@optional
- (void) optionalMethod;
 
 
//  Person.h
 
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
 
@interface Person : NSObject <MyProtocol>
 
@end
 
//  Person.m
 
#import "Person.h"
 
@implementation Person
- (void) requiredMethod{
    NSLog(@"must require!");
}
 
- (void) optionalMethod{
    NSLog(@"may optional!");
}
@end
 
//  main.m
 
#import <Foundation/Foundation.h>
#import "Person.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        [person requiredMethod];
        [person optionalMethod];
    }
    return 0;
}

不务正业之OC(十二) 单例设计模式

单例设计模式:只能创建一个实例

什么时候创建单例:
1、单例对象作为全局数据,可以为其他对象访问
2、如果创建对象时,需要init要做很多事情,那么创建单例可以提高性能

创建单例步骤:
1、创建一个对象的静态实例,初始化为nil
2、当类的实例为nil时,创建类工厂方法
3、覆盖allocWithZone方法,alloc时不会产生新对象
4、实现NSCopying协议,覆盖release、autorelease、retain、retainCount方法,确保单例
5、多线程情况下,@synchronized,保证单例正确初始化

//  Lijie.h
//  Single
 
#import <Foundation/Foundation.h>
 
@interface Lijie : NSObject<NSCopying>
 
@property(nonatomic,retain) NSNumber *age;
@property(nonatomic,retain) NSString *sex;
 
+ (id)sharePerson;
 
@end
 
//  Lijie.m
//  Single
 
#import "Lijie.h"
 
static Lijie *singleLijie = nil;
 
@implementation Lijie
 
+ (id)sharePerson{
    @synchronized(self){
        if (singleLijie == nil) {
            singleLijie = [[[self class] alloc] init];
        }
        return singleLijie;
    }
}
 
+ (id) allocWithZone:(NSZone *)zone{
    if (singleLijie == nil) {
        singleLijie = [super allocWithZone:zone];
    }
    return singleLijie;
}
 
- (id)copyWithZone:(NSZone *)zone{
    return singleLijie;
}
 
- (id)retain{
    return singleLijie;
}
 
- (oneway void)release{
}
 
- (id)autorelease{
    return singleLijie;
}
 
- (NSUInteger) retainCount{
    return UINT_MAX;
}
 
 
@end
 
//  main.m
//  Single
 
#import <Foundation/Foundation.h>
#import "Lijie.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        Lijie *lijie = [Lijie sharePerson];
 
        Lijie *lijie1 = [[Lijie alloc] init];
        Lijie *lijie2 = [Lijie sharePerson];
        Lijie *lijie3 = [lijie1 copy];
 
        [lijie release];
        [lijie release];
        [lijie release];
        [lijie release];
        [lijie release];
        NSLog(@"");//这里搞个breakpoint可以观察lijie1、lijie2、lijie3三个对象地址
    }
    return 0;
}

1

不务正业之OC(十一)–复制对象之深浅Copy

浅Copy只复制对象本身,不对对象属性进行复制。foundatio框架中支持对象Copy的,默认是浅Copy。

#import <Foundation/Foundation.h>
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        NSMutableArray *array = [[NSMutableArray alloc] init];
        for (int i = 1; i < 3; i++) {
            NSObject *obj = [[NSObject alloc] init];
            [array addObject:obj];
            [obj release];
        }
 
        for (NSObject *o in array) {
            NSLog(@"address:%@,retain count:%lu",o,(unsigned long)o.retainCount);
        }
 
        NSMutableArray *arraycopy = [array copy];
        for (NSObject *b in arraycopy) {
            NSLog(@"address:%@,retain count:%lu",b,(unsigned long)b.retainCount);
        }
    return 0;
    }
}
2014-05-03 12:00:44.643 Objcopy[15694:303] address:<NSObject: 0x1002022c0>,retain count:1
2014-05-03 12:00:44.645 Objcopy[15694:303] address:<NSObject: 0x100201b30>,retain count:1
2014-05-03 12:00:44.645 Objcopy[15694:303] address:<NSObject: 0x1002022c0>,retain count:2
2014-05-03 12:00:44.646 Objcopy[15694:303] address:<NSObject: 0x100201b30>,retain count:2

可以发现原对象的地址没发生变化,只是引用计数加1

浅Copy:

//  My.h
//  Copytest
 
#import <Foundation/Foundation.h>
 
@interface My : NSObject<NSCopying>
 
@property(nonatomic,retain) NSString* name;
@property(nonatomic,assign) NSNumber* age;
 
@end
 
//  My.m
//  Copytest
 
#import "My.h"
 
@implementation My
 
//浅Copy
- (id)copyWithZone:(NSZone *)zone{
    My *my = [[[self class] allocWithZone:zone] init];
    my.name = _name;
    my.age = _age;
    return my;
}
@end
 
//  main.m
//  Copytest
#import <Foundation/Foundation.h>
#import "My.h"
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        My *my = [[My alloc] init];
        my.name = @"lijie";
        my.age = @31;
 
        My *my2 = [my copy];
        NSLog(@"%my is address:%p",my);
        NSLog(@"%my2 is address:%p",my2);
 
        NSLog(@"my name address:%p",my.name);
        NSLog(@"my2 name address:%p",my2.name);    
    }
    return 0;
}
//浅Copy的属性变量name指向同一个地址
2014-05-03 12:57:28.264 Copytest[16051:303] my is address:0x100202340
2014-05-03 12:57:28.266 Copytest[16051:303] my2 is address:0x1002033f0
2014-05-03 12:57:28.266 Copytest[16051:303] my name address:0x1f27
2014-05-03 12:57:28.267 Copytest[16051:303] my2 name address:0x1f27

深Copy
只修改copyWithZone方法

#import "My.h"
 
@implementation My
//浅Copy
- (id)copyWithZone:(NSZone *)zone{
    My *my = [[[self class] allocWithZone:zone] init];
    my.name = [_name mutableCopy];//Foundation可复制对象,当我们Copy一个不可变对象时,作用就是retain,cocoa做内存优化。使用mutableCopy,无论对象是否可变,副本是可以变,就实现真正的Copy。Copy可变的对象时,当副本是不可变,也实现Copy
    my.age = [_age copy];
    return my;
}
@end
 
2014-05-03 15:01:59.308 Copytest[16189:303] my is address:0x100203f00
2014-05-03 15:01:59.309 Copytest[16189:303] my2 is address:0x100202ae0
2014-05-03 15:01:59.310 Copytest[16189:303] my name address:0x1000022f0 //地址不一样
2014-05-03 15:01:59.310 Copytest[16189:303] my2 name address:0x100204560

不务正业之OC(十)–复制对象之retain与copy区别

复制对象:创建一副本,开辟一块新的内存空间
实现协议:NSCopying或NSMutableCopying其中之一
注意:Copy产生对象不可变、MutableCopy产生对象可变

//  main.m
//  Objcopy
 
#import <Foundation/Foundation.h>
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        NSMutableArray *muarray = [NSMutableArray arrayWithObjects:@"a",@"b",@"c",nil];
        NSMutableArray *retain_array = [muarray retain];
        [retain_array removeLastObject];
        for (NSString *member in muarray){
            NSLog(@"member is %@",member);
        }
        NSLog(@"retain count %lu",(unsigned long)muarray.retainCount);
        [muarray release];
        NSLog(@"retain count %lu",(unsigned long)muarray.retainCount);
 
        NSLog(@"-----------------------");
        NSMutableArray *muarray2 = [NSMutableArray arrayWithObjects:@"a",@"b",@"c",nil];
        NSMutableArray *copy_array = [muarray2 mutableCopy];
        [copy_array removeLastObject];
        for (NSString *member in muarray2){
            NSLog(@"member is %@",member);
        }
 
    }
    return 0;
}

Copy和NSMutableCopy区别

#import <Foundation/Foundation.h>
 
int main(int argc, const char * argv[])
{
 
    @autoreleasepool {
        NSArray *array1 = [NSArray arrayWithObjects:@"a",@"b",nil];
        NSMutableArray *array2 = [NSMutableArray arrayWithObjects:@"a",@"b",nil];
        [array1 addObject:"c"];//这行代码直接崩溃
        [array2 addObject:@"c"];
        NSLog(@"%@",array2);
    }
    return 0;
}