OC+5-Foundation续&copy&单例模式singleton

NSFileManger的介绍和用法(文件操作)

1、NSFileManager的介绍
     NSFileManager:用来管理文件系统的,进行常见的文件或文件夹操作(拷贝、剪切、创建等)
      NSFileManager使用了单例模式singleton,使用defaultManager方法可以获得那个单例对象

2、NSFileManager的基本使用(常见的判断)
      NSString *filePath = @"/Users/ZacharyUE/Desktop/str.plist ;//先给一个路径
        NSString *filePath2 = @"/Users/ZacharyUE/Desktop" ;
       
//NSFileManager  用于判断
       
// 创建文件管理对象,单例对象(在程序运行期间,只有一个对象存在)
       
NSFileManager *fm = [ NSFileManager defaultManager ];
       
//1 )判断文件是否存在
       
BOOL isYES = [fm fileExistsAtPath :filePath];
       
NSLog ( @"%d" , isYES);
       
//2 )判断是否是一个目录
       
if (isYES) {
           
BOOL isDir;
            [fm
fileExistsAtPath :filePath2 isDirectory :&isDir];
           
if (isDir) {
               
NSLog ( @" 这是一个目录 " );
            }
else {
               
NSLog ( @" 不是一个目录 " );
            }
        }
       
//3 )判断文件是否可读
        isYES = [fm
isReadableFileAtPath :filePath];
       
NSLog ( @"%d" , isYES);
       
//4 )是否可写
        isYES = [fm
isWritableFileAtPath :filePath2];
       
NSLog ( @"%d" , isYES);
       
//5 )是否可删除
        isYES = [fm
isDeletableFileAtPath :filePath];
        NSLog(@"%d", isYES);


3、NSFileManager用法深入1
     - NSFileManager的文件访问
       // 创建文件对象
        NSFileManager *fm = [NSFileManager defaultManager];
        NSString *filePath = @"/Users/ZacharyUE/Desktop/str.plist ;    //文件路径
        NSString *dirPath = @"/Users/ZacharyUE/Desktop/儒释道;         //目录路径
        //1 )何如获取文件的信息(属性)
       
NSDictionary *dic = [fm attributesOfItemAtPath :filePath error : nil ];
       
NSLog ( @"%@" , dic);
       
NSLog ( @"%@, %@" , [dic objectForKey : @"NSFileOwnerAccountName" ], dic[ @"NSFileOwnerAccountName" ]); // 字典通过 key 获取值,两种方式
       
//2 )获取指定目录下文件及子目录
       
// 使用递归的方式   获取当前目录及子目录下的所有文件及文件夹
       
NSArray *arr = [fm subpathsAtPath :dirPath];
       
// 这种方法不是使用递归的方式实现
        arr = [fm
subpathsOfDirectoryAtPath :dirPath error : nil ];
       
NSLog ( @"%@" , arr);
       
//3 )获取指定目录下的子目录(不在获取后代路径 , 即不在获取子目录下的信息)
        arr = [fm
contentsOfDirectoryAtPath :dirPath error : nil ];
        NSLog(@"%@", arr);


4、NSFileManager用法深入2
       // 第一步,必须有文件管理对象
       
NSFileManager *fm = [ NSFileManager defaultManager ];
      
//如何创建目录(路径:/Users/ZacharyUE/Desktop/dir)
        NSString *createDirPath = @"/Users/ZacharyUE/Desktop/dir" ;
       
/*
         createDirectoryAtPath:@"
路径 " withIntermediateDirectories:YES/NO
         YES/NO:
会把缺失文件夹补上来,后者如果上级文件夹确实,会报错
         attributes:
属性的字典 error: 错误对象
        */

       
BOOL isYES = [fm createDirectoryAtPath :createDirPath withIntermediateDirectories : NO attributes : nil error : nil ];
       
if (isYES) {
           
NSLog ( @"%d" , isYES);
        }

// 如何创建文件
        NSString *str = @"shi最棒的!";//写入到@"/Users/ZacharyUE/Desktop/dir/me.txt";
        //以下的 createDirPath = @"/Users/ZacharyUE/Desktop/dir /me.txt " ;
        //1 writeToFile
       
//2 createFileAtPath
       
/*
            createFileAtPath:@"
路径 " contents:NSData 类型的数据 attributes: 文件的属性的字典
        
创建 NSData :是一个处理二进制数据的类
        
NSString-------- NSData
         */

       
NSData *data = [str dataUsingEncoding : NSUTF8StringEncoding ];
       
BOOL isYES = [fm createFileAtPath :createDirPath contents :data attributes : nil ];
        NSLog(@"%d", isYES);

// 如何 copy 文件
       
NSString *copyPath = @"/Users/ZacharyUE/Desktop/dir/xxx/me.txt" ;
       
BOOL isYES = [fm copyItemAtPath :createDirPath toPath :copyPath error : nil ];
        NSLog(@"%d", isYES);

// 如何移动文件
       
NSString *movePath = @"/Users/ZacharyUE/Desktop/dir/aaa/me.txt" ;
        [fm moveItemAtPath:createDirPath toPath:movePath error:nil];

// 如何删除文件, @"/Users/ZacharyUE/Desktop/dir/me.txt"
        [fm removeItemAtPath:createDirPath error:nil];

5、NSFileManager文件下载的思路
     1)发送请求给服务器,要求下载某个文件
     2)服务器发出响应,返回文件数据
     3)手机客户端利用NSData来存放服务器返回的文件数据
     4)利用NSFileManager将NSData里面的文件数据写到新的文件中

6、iOS沙盒(sandbox)机制
   每个iOS应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用的文件系统隔离,iOS系统不允许访问其他应用的应用沙盒。
   在iOS8中已经开放访问(extension),对几个固定系统区域的扩展机制。
   应用沙盒一般包含几个文件目录:应用程序包、Documents、Libaray(子目录Caches和Preferences)、tmp
   应用程序包:包含所有的资源文件和可执行文件。
   Documents:保存应用运行时生成的需要持久化的数据,iTunes会自动备份该目录。
   tmp:保存应用运行时所需的零时数据,使用完后相应地文件从该目录删除。未运行时,系统也可能清除该目录的文件,iTunes不会同步该目录。iPhone重启时,该目录下的文件会丢失。
   Libaray:存储程序的默认设置和其它状态信息,iTunes会自动备份该目录。
    Libaray/Caches:存储缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出时删除。
    Libaray/Preference:保存应用的所有偏好设置(配置信息\SQLite),iOS的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。

// 沙盒路径获取方法:
       
//1 )沙盒的路径
       
NSString *sandBoxPath = NSHomeDirectory ();
       
NSLog ( @"sandBoxPath = %@" , sandBoxPath); // Mac 下,用户根目录
       
//2 tmp 路径
       
NSString *tmpPath = NSTemporaryDirectory ();
       
NSLog ( @"tmpPath = %@" , tmpPath);
       
//2 Documents 路径
      
// NSSearchPathForDirectoriesInDomains( 要查找的目录 , 是否使用主目录 , YES/NO 是否获取全路径 )
       
NSArray *arr = NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES );
       
NSLog ( @"%@" , arr);
       
//4 Library caches 同理
        arr =
NSSearchPathForDirectoriesInDomains ( NSLibraryDirectory , NSUserDomainMask , YES );
       
NSLog ( @"%@" , arr);
       
//5 preferences 路径,在 Libaray 的基础上,拼接 /Preferences
        NSString *filePath = [arr lastObject];
        // stringByAppendingPathComponent用于拼接,也可以创建文件: @“Preferences/a.txt"
        NSString *str = [filePath stringByAppendingPathComponent : @"Preferences" ];
        NSLog(@"%@", str);


7、常见的结构体
1)NSPoint和CGPoint的使用()
     /* Points. */
     //二维平面的一个点
struct CGPoint {
    CGFloat x;
    CGFloat y;
};
typedef struct CGPoint CGPoint;// NSPoint是CGPoint的别名,没区别

CGPoint c1; //c1 CGPoint 结构体类型的变量
        c1.
x = 10 ;
        c1.
y = 10 ;
       
CGPoint c2 = { 10 , 10 };
       
//OC 特有的赋值
       
CGPoint c3 = CGPointMake ( 10 , 10 );
        NSPoint c4 = NSMakePoint(5, 5);


2)NSSize和CGSize的使用(大小)
      /* Sizes. */
     //表示平面的面积
struct CGSize {
    CGFloat width;//宽
    CGFloat height;//高
};
typedef struct CGSize CGSize;

//同理,也有特有的赋值方式,形式与上面类似 CGSizeMake和 NSMake Size
3)NSRect和CGRect的使用(矩形)
/* Rectangles. */
//表示从左上角某个点开始的矩形区域
struct CGRect {
    CGPoint origin;//开始点
    CGSize size;//大小
};
typedef struct CGRect CGRect;

CGRect r1;
        r1.origin.x = 0;
        r1. origin . y = 0 ;
        r1. size . width = 200 ;
        r1. size . height = 80 ;
       
        CGRect r2 = {{ 0 , 0 }, { 10 , 20 }};
        //OC 特有赋值方式
        CGRect r3 = CGRectMake ( 0 , 0 , 30 , 80 );
        NSRect r4 = NSMakeRect(0, 0, 89, 90);
      // 快捷查看值的方法,转换为字符串
        NSLog(@"r4 = %@", NSStringFromRect(r4));
     //同理,上面的Size和Point都可以
4)常见结构体的使用注意
  苹果官方推荐使用CG开头



8、NSNumber的使用
   1)NSNumber的介绍和使用
     OC中处理数字的一个类
     NSArray和NSDictionary中只能存放OC对象,需要先将基本类型包装成对象,这样就可以存放到数组或字典
   2) NSNumber的创建
             int a = 10 ;
       
        NSNumber *intObj = [NSNumber numberWithInt:a];//其他类型同理
        NSArray *array = [ NSArray arrayWithObjects :intObj, nil ];
        NSLog(@"%@", array);
   3)从 NSNumber对象中获取到基本数据类型
         float b = 2.3f ;
       
NSNumber *floatObj = [ NSNumber numberWithFloat :b];
        [array
addObject :floatObj];
       
NSLog ( @"%@" , array);
       
       
// 数组的第一个元素和第二个元素相加
       
//1 )取出数组的元素
       
//2 )把数组元素转换为基本数据类型
       
NSNumber *n1 = array[ 0 ];
       
int a1 = [n1 intValue ]; // 获取对象的整形值
       
       
NSNumber *n2 = array[ 1 ];
       
float b1 = [n2 floatValue ];
        a1 = a1 + b1;
        NSLog(@"%d", a1);

 简写形式@(变量名)@数值@YES,都是把变量、数值或YES包装成对象

9、NSValue的介绍和使用
     NSNumber是NSValue的子类, NSValue主要是把指针,CGRect结构体等包装成OC对象,以便存储。
     (int/float/char/pointers/structures/object ids)
      NSValue类的目标:允许以上数据类型的数据结构能够被添加到集合里,如NSArray和NSDictionary
     为了方便结构体和 NSValue的转换,Foundation提供了一下方法:
     1)存储结构体到集合
      + ( NSValue *)valueWithPoint:( NSPoint )point;
     + (NSValue *)valueWithSize:(NSSize)size;
     + (NSValue *)valueWithRect:(NSRect)rect;

      // 创建一个结构体变量,保存一个点
       
CGPoint p1 = CGPointMake ( 10 , 10 );
       
// 将结构体包装为 NSValue 对象
       
NSValue *pointObj = [ NSValue valueWithPoint :p1];
       
NSMutableArray *array = [ NSMutableArray arrayWithObjects :pointObj, nil ];
       
NSLog ( @"%@" , array);
       
       
// 创建一个结构体,保存 Size
       
CGSize s1 = CGSizeMake ( 20 , 20 );
       
NSValue *sizeObj = [ NSValue valueWithSize :s1];
        [array
addObject :sizeObj];
       
NSLog ( @"%@" , array);
       
// 创建一个结构体,保存 Rect
       
CGRect r1 = CGRectMake ( 1 , 1 , 22 , 33 );
        [array
addObject :[ NSValue valueWithRect :r1]];
        NSLog(@"%@", array);
     2)从NSValue对象取出之前包装的结构体
     - (NSPoint)pointValue;
      - (NSSize)sizeValue;
      - (NSRect)rectValue;
     
      // 取最后的值
       
NSValue *lastValue = [array lastObject ];
       
NSRect r2 = [lastValue rectValue ];
        NSLog(@"%@", NSStringFromRect(r2)); // 转换为字符串

// 自定义结构体
typedef struct data {
   
int year;
   
int month;
   
int day;
} MYData;

// 定义结构体变量
       
MYData md = { 2015 , 9 , 3 };
       
// 将自定义结构体包装成 NSValue 对象
       
//@encode(MYData) 作用,把 MYData 类型生成一个常量字符串描述
       
NSValue *mdObj = [ NSValue valueWithBytes :&md objCType : @encode ( MYData )];
       
// 保存自定义结构体,到数组
       
NSMutableArray *arr = [ NSMutableArray arrayWithObjects :mdObj, nil ];
       
// 从数组取出 NSValue 对象
       
MYData md1;
       [[arr objectAtIndex : 0 ] getValue :&md1]; //getValue 获取的值,保存到 md1
        // 从对象中,取出结构体变量的值
        NSLog(@"%d-%d-%d", md1.year, md1.month, md1.day);



10、NSDate的介绍和使用
1)NSDate的介绍和使用
NSDate可以表示时间,可以进行一些常见的日期、时间处理。一个 NSDate对象就代表一个时间,[ NSDate date]返回的就是当前时间。
//NSDate OC 中提供日期时间处理的一个类
       
//1 )获取当前时间
       
NSDate *d1 = [ NSDate date ]; // 创建一个日期时间对象对象
       
// 北京东八区,打印的时间 ( 格林威治时间 )+8 = 现在时间
        NSLog(@"%@", d1);

        //2 )格式化显示时间
       
NSDateFormatter *formatter = [ NSDateFormatter new ];
       
// 设置日期的显示格式
       
//yyyy: 年份   MM: 月份     dd: 天数
       
//HH:24 小时制   hh:12 小时制
       
//mm: 分钟数     ss: 秒数
        formatter.
dateFormat = @"yyyy MM dd HH:mm:ss" ;
       
NSString *dateStr = [formatter stringFromDate :d1];
        NSLog(@"%@", dateStr);

         //3 )计算时间
           
//1 、计算明天的此刻时间( 24 小时之后的时间)
       
NSTimeInterval t = 60 * 60 * 24 ;
       
NSDate *tom = [ NSDate dateWithTimeIntervalSinceNow :t];
       
       
NSDateFormatter *formatter = [ NSDateFormatter new ]; // 格式化显示
        formatter.
dateFormat = @"yyyy-MM-dd hh:mm:ss" ;
       
NSString *str = [formatter stringFromDate :tom];
       
NSLog ( @"%@" , str);
           
//2 、计算昨天的此刻时间( -t 24 小时之前的时间)
       
NSDate *yest = [ NSDate dateWithTimeIntervalSinceNow :-t];
        str = [formatter
stringFromDate :yest];
       
NSLog ( @"%@" , str);
           
// 也可以用当前时间,进行加减时间
       
NSDate *now = [ NSDate date ];
       
NSDate *yest2 = [now addTimeInterval :-t]; // 该方法已经被放逐了
        str = [formatter
stringFromDate :yest2];
        NSLog(@"%@", str);

         //4 )日期时间对象的使用
           
//1 NSCalendar 日期类,可以帮助快速获取年月日 时分秒的信息
       
NSDate *d = [ NSDate date ];
       
// 创建日期对象
       
NSCalendar *cal = [ NSCalendar currentCalendar ];
       
// 参数:获取日期的哪个单元 ( 可以多个单元, |)         当前日期对象
       
NSDateComponents *com = [cal components : NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate :d];
       
NSLog ( @"%ld-%ld-%ld" , com. year , com. month , com. day );
            //2、时间差方法:components:<#(NSCalendarUnit)#> fromDate:<#(nonnull NSDate *)#> toDate:<#(nonnull NSDate *)#> options:<#(NSCalendarOptions)#>



11、集合对象的内存管理
1)集合内存管理
                    // 创建对象
       
Person *p = [ Person new ]; //1
       
// 定义数组,并且把 P 放到数组中
       
// 规律:只要把对象放入数组, retainCount+1
        //NSArray *arr = [NSArray arrayWithObject:p];//2
        NSMutableArray *arr = [ NSMutableArray array ];
        [arr addObject :p]; //2
//上面都是快速创建对象,会被加入自动释放池。如果是[[NSArray alloc] init]、copy或new,则不会加入自动释放池,则该对象不会被释放,不会调用dealloc
        NSLog ( @"p.retainCount = %lu" , p. retainCount );
        [p
release ];
       
// 规律 2 :数组被销毁时,对对象发送了一次 release 消息
       
// 销毁顺序:数组先挂 ----- 》数组向其中的对象也发送 release
       
NSLog ( @"p.retainCount = %lu" , p. retainCount );
       
// 结论:
       
//1 )当对象被添加到数组中,对象的引用计数 +1
       
//2 )数组被销毁时,对对象发送了一次 release 消息
        //3)数组被销毁了,其中的对象不一定被销毁    
2)集合内存管理总结
1、当调用alloc、new、copy(mutablecopy)方法产生一个新对象的时候,就必须在最后调用一次release或者autorelease。因为不会加入自动释放池。
2、retain和release必须成对出现
3、当一个对象添加集合,retain+1,retainCount+1
   当一个集合(快速创建)被销毁,集合所有对象均被release一次,retainCount-1
   当一个对象从集合中移除,这个对象会被release一次,retainCount-1
4、普遍规律:当方法名是add\insert开头   计数器+1
           当方法名是remove\delete开头,计数器-1



12、copy概念及入门
1、copy概念
copy:复制,拷贝,是产生一个副本的过程。
对象拷贝的目的:要使用某个对象的数据,但是在修改对象的时候不影响原来的对象内容。 源文件和副本文件,互不影响。
copy功能:一个对象可以调用copy或mutableCopy方法创建一个副本对象
        copy:创建不可变副本(如NSString)
        mutableCopy:创建可变副本(如NSMutableString)
copy功能的前提:1)浅拷贝copy:需要遵守NSCopy协议,实现copyWithZone:方法
                  @protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
   @end   
              2)深拷贝mutableCopy:需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法
                                                 @protocol NSMutableCopying
- ( id )mutableCopyWithZone:( nullable NSZone *)zone;
   @end
2、copy快速入门
不可变对象,copy      产生不可变对象
不可变对象,mutableCopy   产生可变对象
可变对象,copy         产生不可变对象
可变对象,mutableCopy   产生可变对象


13、copy与内存管理
浅拷贝:只是拷贝了地址,并没有真正的分配新的内存空间(源对象引用计数+1,副本对象指向源对象,两者一样)
深拷贝:分配了新的内存空间(源对象引用计数不变,副本对象为1)

14、@property中的copy关键字
1)MRC
     1、copy:只用于NSString和block
     2、retain:除NSString和block以外的对象
     3、assign:基本数据类型、枚举、结构体(非OC对象)。当两个对象互相引用时,一段assign,一段retain
2)ARC
     1、 copy:只用于NSString和block
     2、strong: 除NSString和block以外的对象
     3、weak:当两个对象互相引用时,一段weak,一段strong
     4、assign: 基本数据类型、枚举、结构体(非OC对象)

@property ( nonatomic , copy ) NSString *name;
#import <Foundation/Foundation.h>
#import "Person.h"

int main( int argc, const char * argv[]) {
   
@autoreleasepool {
   
       
Person *p = [[ Person alloc ] init ];

       
NSMutableString *str = [ NSMutableString string ];
        [str
appendString : @"xxx" ];
        p.
name = str;
       
NSLog ( @"%@" , p. name );
       
// 使用 copy 时,防止这种无理的赋值。 name 得到的只是 str 的副本,再改变 str 不会影响 name
        [str
appendString : @"ooo" ];
       
NSLog ( @"%@" , p. name );
       
       
       
       
       
        [p
release ];
    }
   
return 0 ;
}


15、为自定义的类实现copy操作
步骤:1、新建Person类
     2、为Person类实现copy操作
          1)让Person类遵守NSCopying协议
          2)实现copyWithZone方法,该方法返回一个对象的副本
          3)在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,且返回该对象
     3、创建Person对象,调用copy方法,查看地址
参数zone:表示空间,指定了zone,就可以指定新建对象对应的内存空间。如今开发中,zone几乎可以忽略

例子:1、 @interface Dog : NSObject < NSCopying >
@property ( nonatomic , assign ) int tuiNum;
@property ( nonatomic , assign ) int speed;
@end

     2、 @implementation Dog
- (id)copyWithZone:(nullable NSZone *)zone {
   
   
    NSLog ( @"copy 完毕 " );
    // 互不影响,需申请新空间
    Dog *d = [[ Dog alloc ] init ];
    d. speed = self . speed ;
    d. tuiNum = self . tuiNum ;
    // 返回新空间的地址
    return d;
}
@end

3、  
       
Dog *dog = [ Dog new ];
        dog.
speed = 230 ;
        dog.
tuiNum = 8 ;
       
// 虽然重写 copyWithZone 方法,依然调用 copy 。历史原因
       
Dog *yellowDog = [dog copy ];
        NSLog(@"%d,%d", yellowDog.speed, yellowDog.tuiNum);



16、简单的单例模式实现
1)理解单例模式概念
单例模式(singleton):类的对象成为系统中唯一的实例,提供一个访问点,供客户类共享资源
单例使用场景:1、类只能够有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法
            2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码
2)单例模式的实现
1、SingletonTools单例工具类
#import <Foundation/Foundation.h>

@interface SingletonTools : NSObject < NSCopying >
@property ( nonatomic , assign ) int num;
@property ( nonatomic , copy ) NSString *text;
// 单例的类,提供一个接入点
+(
instancetype )shareInstances;
// 防止创建新的对象或者破坏该单例对象 ,需重写以下方法
-( id )copyWithZone:( NSZone *)zone;
+(
id )allocWithZone:( NSZone *)zone;
-(
id )retain;
-(
NSUInteger )retainCount;
-(
oneway void )release;
-(
id )autorelease;
@end
-------------------------------------------------------------------------------
#import "SingletonTools.h"
// 定义一个全局变量
static SingletonTools *instances = nil ; //static 增长使用周期,下次使用还有值
@implementation SingletonTools
// 单例接入点方法
+(
instancetype )shareInstances {
   
// 目的:保证对象必须唯一
   
if ( instances == nil ) {
       
// 创建一个对象
       
instances = [[ SingletonTools alloc ] init ];
       
return instances ;
    }
   
return instances ;
}

// 防止创建新的对象或者破坏该单例对象,需重写以下方法
-(
id )copyWithZone:( NSZone *)zone {
   
return self ;
}
+(
id )allocWithZone:( NSZone *)zone {
   
// 线程保护
   
@synchronized ( self ) {
       
if ( instances == nil ) {
           
// 调用父类 alloc
           
instances = [ super allocWithZone :zone];
           
return instances ;//此处有待考究,没有关锁,就退出了
        }
       
return instances ;
    }
}
-(
id )retain {
   
return self ;
}
-(
NSUInteger )retainCount {
    return   1;
}
-(
oneway void )release {
   
}
-(
id )autorelease {
   
return self ;
}
@end



2、Person类
#import <Foundation/Foundation.h>

@interface Person : NSObject
-(
void ) run;
@end
----------------------------------------------------------------------------------------
#import "Person.h"
#import
"SingletonTools.h"
@implementation Person
-(
void ) run {
   
// 创建单例对象
   
SingletonTools *st = [ SingletonTools shareInstances ];
    st.
num = 500 ;
    st.
text = @"xxxxx" ;
}
@end



3、Dog类
#import <Foundation/Foundation.h>

@interface Dog : NSObject
-(
void )run;
@end
--------------------------------------------------------------------------------------
#import "Dog.h"
#import
"SingletonTools.h"
@implementation Dog
-(
void )run {
   
SingletonTools *st = [ SingletonTools shareInstances ];
   
NSLog ( @"%d,%@" , st. num , st. text );
}

@end



4、main
#import <Foundation/Foundation.h>
#import
"Person.h"
#import
"Dog.h"

int main( int argc, const char * argv[]) {
   
@autoreleasepool {
       
Person *p = [ Person new ];
        [p
run ];
       
       
Dog *d = [ Dog new ];
        [d
run ]; // 通过单例, d 也可以访问 p 的数据
       
// 而且在重写方法后,并不需要在意在 Dog 类的 run 中是如何创建单例对象(快速或者 alloc
       
// 单例实现了两个不相干的类的数据传输
    }
   
return 0 ;
}
Console:500,xxxxx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值