6.12考核

1.创建一个单例类

接口部分

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface singleCase1 : NSObject
+ (id) instance;
+ (void) print;
@end

NS_ASSUME_NONNULL_END

实现部分

#import "singleCase1.h"

@implementation singleCase1
static id _singleCase = nil;
+ (id) instance {
        if(_singleCase == nil) {
            NSLog(@"正在创建单例");
            _singleCase = [[singleCase1 alloc] init];
        }
    
    return _singleCase;
}
+ (void) print{
    NSLog(@"正在使用单例");
}
@end

使用单例:

#import <Foundation/Foundation.h>
#import "singleCase1.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [singleCase1 instance];
        [singleCase1 print];
        [singleCase1 instance];
        [singleCase1 instance];
        [singleCase1 instance];
    }
    return 0;
}

结果:

2022-06-13 17:03:31.648673+0800 6月12日考核[1061:7897944] 正在创建单例
2022-06-13 17:03:31.648858+0800 6月12日考核[1061:7897944] 正在使用单例
Program ended with exit code: 0

在调用print方法后有调用了三次instance方法,但只打印了一行“正在创建单例”,证明singleCase1单例没有被重复创建。

新建一个Person类:

  • 用属性关键字给该类写name、age两个属性
  • 重写初始化方法,初始化的同时能给name、age两个属性赋值
  • 在main函数里打印出name、age两个属性的值,检查初始化是否成功

重写父类初始化方法的模板如下

- (instancetype) init {
	if(self = [super init]) {
		//重写的初始化代码;
	}
	return self;
}

Person的接口部分

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, assign) int age;
@end

NS_ASSUME_NONNULL_END

Person实现部分

#import "Person.h"

@implementation Person
- (instancetype) init {
    if(self = [super init]) {
        _name = @"superman";
        _age = 40;
    }
    return self;
}
@end

使用Person类

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person* person1 = [[Person alloc] init];
        NSLog(@"%@, %d", person1.name, person1.age);
    }
    return 0;
}

结果:

2022-06-13 17:14:26.101529+0800 6月12日考核[1161:7903241] superman, 40
Program ended with exit code: 0

新建一个XiyouMoubilePerson类

  • 该类继承于Person类
  • 该类设置4个成员变量(前两个为int型,后两个为NSString型:四个成员变量依次为iOS、web、andriod、server),将四个成员变量隐藏:同一个类或子类中才有权访问到
  • 设置四个成员变量对应的set、get方法
  • 重写iOS变量的set方法:如果为奇数则值+1,偶数则值-1

XiyouMobilePerson类接口部分

#import "Person.h"

NS_ASSUME_NONNULL_BEGIN

@interface XiyouMobilePerson : Person {
    int _iOS;
    int _web;
    NSString* _andriod;
    NSString* _server;
}
- (void) setiOS: (int) num;
- (void) setWeb: (int) num;
- (void) setAndriod: (NSString*) NSString;
- (void) setServer: (NSString*) NSString;
- (int) getiOS;
- (int) getWeb;
- (NSString*) getAndriod;
- (NSString*) getServer;
@end

NS_ASSUME_NONNULL_END

将四个变量设置为成员变量即可达到隐藏的效果:才同一个类或子类中才可以访问到
成员变量一般采用 _变量名 的形式,变量名全部使用小写字母。

XiyouMobilePerson的实现部分

#import "XiyouMobilePerson.h"

@implementation XiyouMobilePerson
//这里的iOS的set方法已经时重写过的
- (void) setiOS: (int) num {
    if(num % 2 == 0) {
        num-=1;
    } else {
        num+=1;
    }
    _iOS = num;
}
- (void) setWeb: (int) num {
    _web = num;
}
- (void) setAndriod: (NSString*) nsstring {
    _andriod = nsstring;
}
- (void) setServer:(NSString *) nsstring {
    _server = nsstring;
   
}
- (int) getiOS {
    return _iOS;
}
- (int) getWeb {
    return _web;
}
- (NSString*) getAndriod {
    return _andriod;
}
- (NSString*) getServer {
    return _server;
}
@end

使用XiyouMobilePerson

#import <Foundation/Foundation.h>
#import "XiyouMobilePerson.h"
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        XiyouMobilePerson* xiyouPerson = [[XiyouMobilePerson alloc] init];
        //对xiyouPerson使用set方法赋值
        [xiyouPerson setiOS:20];
        [xiyouPerson setWeb:40];
        [xiyouPerson setAndriod:@"i am andriod!"];
        [xiyouPerson setServer:@"i am server!"];
        //使用get方法来输出成员变量的值
        NSLog(@"%d", [xiyouPerson getiOS]);
        NSLog(@"%d", [xiyouPerson getWeb]);
        NSLog(@"%@", [xiyouPerson getAndriod]);
        NSLog(@"%@", [xiyouPerson getServer]);
    }
    return 0;
}

输出结果

2022-06-13 17:44:13.124709+0800 6月12日考核[1511:7917888] 19
2022-06-13 17:44:13.125255+0800 6月12日考核[1511:7917888] 40
2022-06-13 17:44:13.125297+0800 6月12日考核[1511:7917888] i am andriod!
2022-06-13 17:44:13.125326+0800 6月12日考核[1511:7917888] i am server!
Program ended with exit code: 0

新建一个Model类

  • 定义一个类型为NSMutableArray属性,名称为xiyouMobileArray。注意xiyouMobileArray里存放的是XiyouMobilePerson类对象,主要考察属性关键字。

Model的接口部分


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Model : NSObject
@property (nonatomic, strong) NSMutableArray* xiyouMobileArray;
@end

NS_ASSUME_NONNULL_END

Model的实现部分

#import "Model.h"

@implementation Model

@end

关于属性关键字strong和weak:

  • 使用strong关键字的属性是强引用的,无法被系统回收
  • 使用weak关键字的属性是弱引用,可能会被回收

定义一个Demand协议

  • 协议中声明一个calculate方法:关键字为必需实现。
  • 协议中声明一个unnecessary方法:关键字为可选实现。
  • 在XiyouMobilePerson类中遵循这个协议。
  • 在XiyouMobilePerson类中重写calculate方法:打印iOS与web两个变量相加后的值。

Demand协议内容:

#import <Foundation/Foundation.h>
#ifndef Demand_h
#define Demand_h
@protocol Demand <NSObject>
@required
    - (void) calculate;
@optional
    - (void) unnecessary;
@end

#endif /* Demand_h */

在这里插入图片描述

XiyouMobilePerson.m:

#import "XiyouMobilePerson.h"

@implementation XiyouMobilePerson
- (void) setiOS: (int) num {
    if(num % 2 == 0) {
        num-=1;
    } else {
        num+=1;
    }
    _iOS = num;
}
- (void) setWeb: (int) num {
    _web = num;
}
- (void) setAndriod: (NSString*) nsstring {
    _andriod = nsstring;
}
- (void) setServer:(NSString *) nsstring {
    _server = nsstring;
   
}
- (int) getiOS {
    return _iOS;
}
- (int) getWeb {
    return _web;
}
- (NSString*) getAndriod {
    return _andriod;
}
- (NSString*) getServer {
    return _server;
}

- (void) calculate {
    NSLog(@"iOS和web之和为:%d", _iOS + _web);
}
@end


XiyouMobilePerson.h:

#import "Demand.h"
#import "Person.h"

NS_ASSUME_NONNULL_BEGIN


@interface XiyouMobilePerson : Person  <Demand>{
    int _iOS;
    int _web;
    NSString* _andriod;
    NSString* _server;
}
- (void) setiOS: (int) num;
- (void) setWeb: (int) num;
- (void) setAndriod: (NSString*) NSString;
- (void) setServer: (NSString*) NSString;
- (int) getiOS;
- (int) getWeb;
- (NSString*) getAndriod;
- (NSString*) getServer;
@end

NS_ASSUME_NONNULL_END

主函数:

#import <Foundation/Foundation.h>
#import "singleCase1.h"
#import "Model.h"
#import "XiyouMobilePerson.h"
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        XiyouMobilePerson* xiyouPerson = [[XiyouMobilePerson alloc] init];
        //对xiyouPerson使用set方法赋值
        [xiyouPerson setiOS:20];
        [xiyouPerson setWeb:40];
        [xiyouPerson setAndriod:@"i am andriod!"];
        [xiyouPerson setServer:@"i am server!"];
        //使用get方法来输出成员变量的值
        NSLog(@"%d", [xiyouPerson getiOS]);
        NSLog(@"%d", [xiyouPerson getWeb]);
        NSLog(@"%@", [xiyouPerson getAndriod]);
        NSLog(@"%@", [xiyouPerson getServer]);
        [xiyouPerson calculate];
    }
    return 0;
}

2022-06-13 20:40:54.414177+0800 6月12日考核[3508:7987723] 19
2022-06-13 20:40:54.414357+0800 6月12日考核[3508:7987723] 40
2022-06-13 20:40:54.414386+0800 6月12日考核[3508:7987723] i am andriod!
2022-06-13 20:40:54.414404+0800 6月12日考核[3508:7987723] i am server!
2022-06-13 20:40:54.414432+0800 6月12日考核[3508:7987723] iOS和web之和为:59
Program ended with exit code: 0

可以看到最后一句正确输出了_iOS和_web之和,证明协议定义的方法被实现。

(一般对成员变量的set方法是直接用成员变量去掉 “_”的名字,如_iOS的set方法是iOS,上面写成setiOS并不准确,但不影响方法的实现和运行)

main函数的操作:

  • 新建一个Model对象,在其属性xiyouMobileArray中添加五名XiyouMobilePerson对象的信息(信息值随意输入,变量类型匹配即可)
  • 在上述xiyouMobileArray数组中,打印iOS变量值最大的对象的相关信息
  • 删除上述xiyouMobileArray数组中range为(2, 3)的成员

代码部分:

#import <Foundation/Foundation.h>
#import "singleCase1.h"
#import "Model.h"
#import "XiyouMobilePerson.h"
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        XiyouMobilePerson* xiyouPerson1 = [[XiyouMobilePerson alloc] init];
        [xiyouPerson1 setiOS:280];
        XiyouMobilePerson* xiyouPerson2 = [[XiyouMobilePerson alloc] init];
        [xiyouPerson2 setiOS:12];
        XiyouMobilePerson* xiyouPerson3 = [[XiyouMobilePerson alloc] init];
        [xiyouPerson3 setiOS:24];
        XiyouMobilePerson* xiyouPerson4 = [[XiyouMobilePerson alloc] init];
        [xiyouPerson4 setiOS:999];
        XiyouMobilePerson* xiyouPerson5 = [[XiyouMobilePerson alloc] init];
        [xiyouPerson5 setiOS:100];
        Model* model = [[Model alloc] init];
        model.xiyouMobileArray = [NSMutableArray arrayWithArray:@[xiyouPerson1, xiyouPerson2, xiyouPerson3, xiyouPerson4, xiyouPerson5]];
        for (XiyouMobilePerson* obj in model.xiyouMobileArray) {
            NSLog(@"%d", [obj getiOS]);
        }
		//用代码块来来排序创建一个新的数组
        NSMutableArray* array1 = [model.xiyouMobileArray sortedArrayUsingComparator: ^(id obj1, id obj2)
        {
            if ([obj1 getiOS] > [obj2 getiOS]) {
                return NSOrderedDescending;
            }
            if ([obj1 getiOS] < [obj2 getiOS]) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
        }];
        //由小到大的顺序排序后,最后一个对象的iOS值最大:
        NSLog(@"%d", [array1[4] getiOS] );
    }
    return 0;
}

2022-06-14 17:41:41.504705+0800 6月12日考核[16086:8390126] 279
2022-06-14 17:41:41.504906+0800 6月12日考核[16086:8390126] 11
2022-06-14 17:41:41.504925+0800 6月12日考核[16086:8390126] 23
2022-06-14 17:41:41.504937+0800 6月12日考核[16086:8390126] 1000
2022-06-14 17:41:41.504947+0800 6月12日考核[16086:8390126] 99
2022-06-14 17:41:41.504966+0800 6月12日考核[16086:8390126] 1000
Program ended with exit code: 0

客观题

1.属性和成员变量的区别:

属性自动合成存取方法,可以使用点语法来进行快捷操作。
成员变量受保护,只能在类内部和子类中访问,不能直接被访问。

2.==和isEqual区别;

==是看地址来进行判断,地址不一致即返回false
isEqual:是专门用于判断的方法,不一定是看地址,也可以是其他的标准。

在NSObject类中,==与isEqual:没有明显区别,但在NSString中,已经完成了重写,只要字符串字符序列相同,isEqual:方法就返回true。

在NSString中,有一个专门判断字符序列的方法:isEqualToString:。

3. 分类和扩展能否添加属性:

分类不能添加属性,扩展可以添加属性。

4.NSString的三种类型及其创建方式:

_NSCFContantString: 常量字符串,是一种编译时常量

_NSCFString:
__NSCFString 对象是在运行时创建的一种 NSString 子类,他并不是一种字符串常量。所以和其他的对象一样在被创建时获得了 1 的引用计数。
如果字符串长度大于9或者如果有中文或其他特殊符号(可能是非 ASCII 字符)存在的话则会直接成为 __NSCFString 类型

_NSTaggedPointerString:
对于 NSString 对象来讲,当非字面值常量的数字,英文字母字符串的长度小于等于 9 的时候会自动成为 NSTaggedPointerString 类型。(字符串含q时是小于等于7)
详细内容参看下方链接:

[iOS开发]NSString的三种类型管理方式

5. 容器类的完全深拷贝的两种方法:

  • 对于不可变的容器对象,copy是浅拷贝,mutablecopy是深拷贝。
  • 对于可变对象的拷贝都是生成一个新对象,即深拷贝。
    对于数组而言,元素对象始终是浅拷贝。与非容器类相同。
    集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。

那么如何进行完全深复制呢?

有两种方法来进行深拷贝:
第一种:

NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];

注意:集合中的对象必须遵循NSCopying协议
如果用这种方法深复制,集合里的每个对象都会收到 copyWithZone: 消息。

如果集合里的对象遵循 NSCopying 协议,那么对象就会被深复制到新的集合。

如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深复制,会在运行时出错。
[iOS开发]深拷贝与浅拷贝

第二种:

NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

将集合进行归档,然后解档。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值