iOS组考核题总结
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)
详细内容参看下方链接:
5. 容器类的完全深拷贝的两种方法:
- 对于不可变的容器对象,copy是浅拷贝,mutablecopy是深拷贝。
- 对于可变对象的拷贝都是生成一个新对象,即深拷贝。
对于数组而言,元素对象始终是浅拷贝。与非容器类相同。
集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。
那么如何进行完全深复制呢?
有两种方法来进行深拷贝:
第一种:
NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];
注意:集合中的对象必须遵循NSCopying协议
如果用这种方法深复制,集合里的每个对象都会收到 copyWithZone: 消息。
如果集合里的对象遵循 NSCopying 协议,那么对象就会被深复制到新的集合。
如果对象没有遵循 NSCopying 协议,而尝试用这种方法进行深复制,会在运行时出错。
[iOS开发]深拷贝与浅拷贝
第二种:
NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:oldArray]];
将集合进行归档,然后解档。