便利构造器、单件模式

1.方法

冒号属于方法的一部分

-代表实例方法,必须通过对象调用的方法。

+代表静态方法(类方法)。

2.类方法的特点与用处:通过类就可以直接调用类方法

特点:

  • 静态变量用在对象的语言中:当静态变量声明在类中,这个静态变量归该类所有,同时这个类产生的对象共享(可设置和访问)该变量。
  • 静态变量只初始1次,必须有默认值。
  • 类中静态的变量、方法先初始化,实例的变量、方法后初始化。因此类方法里面不能访问实例变量、方法,只能访问静态变量、方法。

常用于:

  • 定义工具类(如下载工具:int download(file,url);面向过程,与实例的东西完全无关):好处不用创建对象,没alloc和init对象,类直接调用类方法,省去定义成员变量等等麻烦。
  • 构建便利构造器(工厂模式): 不用重新再在主函数上alloc对象,另外还有关内存释放的好处。缺点工厂出问题,对象就没了。
  • 构建单例(单件模式):

3.单例模式

  • 整个程序运行周期里,对象只存在一个。
  • 静态变量不会自释放,在运行过程中长驻内存,当程序结束时才会回收。
  • 常用于:操作音频、数据库、文件、控制程序命令。
  • 好处:因为存储在静态区内,所以当程序运行,访问快速方便。作用共享信息,还有减小对象间的依赖关系。常用于存储一些常用的信息。缺点:存在负荷问题。
  • 特点:单例的获取方法是唯一的,在该静态方法已初始化好唯一一个对象。单例向整个系统公开这实例([静态类名  类方法] == 实例对象)接口,其它类导头文件即可使用。单例向整个系统统一了接口模式([静态类名  类方法].属性)。
  • 单例模式与工厂模式区别:工厂可以建多个对象,单例只建1个。

4.选择类型:SEL  变量名 =  @select(方法:);

5.load与initialize共同点:都只执行1次。区别:load要比initialize先执行,load在编译时执行,initalize在第1次发送消息前执行。

在xcode上Build Phases可增删需编译的文件。

6.全局变量与成员变量区别:全局变量只供本类使用,要使其子类都不能使用的话需加@private修饰。成员变量供本类(定义时有下划线)与类外(不用下划线)使用,需声明和实现属性。成员变量的范围广。

7.

+(void)load
{
    NSLog(@"%s",__func__);//宏func代表当前方法load的名字,常用于调试
}


Student.h

@interface Student : NSObject
{
    int _age;
    NSString *_name;
    NSString *_address;
}

@property(nonatomic,assign)int age;
@property(nonatomic,retain)NSString *name;
@property(nonatomic,retain)NSString *address;
/*
//实例方法
-(void)setName:(NSString *)aName
           Age:(int)aAge
       Address:(NSString *)aAddress;

+(int) addNum1:(int)aNum1
          Num2:(int)aNum2;
*/
//
-(Student *)initWithName:(NSString *)aName
                     Age:(int)aAge
                 Address:(NSString *)aAddress;
-(void)learn;
+(int)count;
+(Student *)studentWithName:(NSString *)aName
                        Age:(int)aAge
                    Address:(NSString *)aAddress;
@end

Student.m

#import "Student.h"
#import "Appinstance.h"
//声明静态变量
static int count = 0;
@implementation Student

@synthesize name = _name,address = _address,age = _age;

/*
-(void)setName:(NSString *)aName
           Age:(int)aAge
       Address:(NSString *)aAddress
{
    self.name = aName;
    self.age = aAge;
    self.address = aAddress;
}

+(int) addNum1:(int)aNum1
          Num2:(int)aNum2
{
    return aNum1 + aNum2;
}
*/
-(Student *)initWithName:(NSString *)aName
                     Age:(int)aAge
                 Address:(NSString *)aAddress
{
    if(self = [super init])
    {
        self.name = aName;
        self.age = aAge;
        self.address = aAddress;
        count++;
        
        [Appinstance shareInstance].cityCode = 020;//统一了接口模式
    }
    return self;
}

-(void)learn
{
    NSLog(@"%d 学习IOS",count);
    NSLog(@"%@ 也在学",self.name);
}
#pragma mark -静态方法-
+(int)count
{
    return count;
}

+(Student *)studentWithName:(NSString *)aName
                        Age:(int)aAge
                    Address:(NSString *)aAddress
{
    Student *s = nil;
    s = [[Student alloc]initWithName:aName Age:aAge Address:aAddress];
    return s;
}
//
+(void)load
{
    NSLog(@"%s",__func__);//宏func代表当前方法load的名字,常用于调试
}
+(void)initialize
{
    NSLog(@"%s",__func__);
}
@end

单例模式

Appinstance.h

@interface Appinstance : NSObject
{
    int _cityCode;
}

@property(nonatomic,assign)int cityCode;

//声明单例方法
+(Appinstance *)shareInstance;

@end

Appinstance.m

#import "Appinstance.h"
//声明静态变量
static Appinstance *instance = nil;

@implementation Appinstance

@synthesize cityCode = _cityCode;

+(Appinstance *)shareInstance
{
    if (!instance)
    {
        instance = [[Appinstance alloc]init];
    }
    return instance;
}
@end

AppDelegate.m

#import "AppDelegate.h"
#import "Student.h"
#import "Appinstance.h"

#include <objc/runtime.h>
#include <objc/objc-runtime.h>
//import与include区别?
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
//    int r = 0;
//    r = [Student addNum1:1 Num2:1];
//    NSLog(@"r = %d",r);
    /*
    Student *s = [[Student alloc]initWithName:@"bill" Age:67 Address:@"usa"];
    [s learn];
    
    Student *s1 = [[Student alloc]initWithName:@"jobs" Age:100 Address:@"usa"];
    [s1 learn];

    Student *s2 = [[Student alloc]initWithName:@"hen" Age:32 Address:@"uk"];
    [s2 learn];

    int c = [Student count];
    NSLog(@"count = %d",c);
    
    Student *s4 = [Student studentWithName:@"killer"
                                       Age:16
                                   Address:@"uk"];
    //向s4发送learn消息
    //[s4 learn];
    
    //这是个编译过程,这两个语句实质是c语言加了运行时,等价于[s4 learn]
    SEL learnSEL = @selector(learn);
    //NSLog(@"sel = %d",learnSEL);//实质整形
    objc_msgSend(s4, learnSEL);
    
    [Appinstance shareInstance].cityCode = 010;
    
    //NSTimer?
    */
    [Student alloc];
    //....................................................
    [self.window makeKeyAndVisible];
    return YES;
}