iOS APP 开发 OC 第二十天,@class 物件互相引用 重现文字狱烧书,苏轼冤狱而死。

tags: OC 30 day

创建一个类

如何创建一个书的class?
首先点击add File的按钮

创建一个Book的 .h .m 档案。

第一个任务,为Book这个类别添加以下属性与方法。

property Type
name NSString
authorName NSString
castKnowledge parameter return
Text void void

如何做到呢?

在.h 档案里面加入属性与方法。

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject

/// 书名
@property(nonatomic,retain)NSString *name;

/// 作者名称
@property(nonatomic,retain)NSString *authorName;

/// 传播知识
- (void)castKnowledge;
@end

NS_ASSUME_NONNULL_END

property 的属性
nonatomic:如果写nonatomic 这个时候生成的setter方法的代码就不会加线程安全锁。特点:不安全,效率高。
retain:生成的setter方法的实现就是标准的MRC内存管理代码。也就是先判断新旧对象是否为同一个对象。如果不是release旧的 retain 新的。
参考文章

小技巧:
快速加入注解
快捷键:command+option+/

接着定义method。

#import "Book.h"

@implementation Book

- (void)castKnowledge
{
    NSLog(@"书中自有黄金屋,书中自有颜如玉!");
}

@end

还没结束!!
我们还要配置MRC的设定
配置dealloc,烧书

#import "Book.h"

/// 释放
@implementation Book
- (void)dealloc
{
    NSLog(@"书被烧了");
    [self.name release];
    [self.authorName release];
    [super dealloc];
}
/// 传播知识的方法
- (void)castKnowledge
{
    NSLog(@"书中自有黄金屋,书中自有颜如玉!");
}

@end

接着,创建一个Person,并让它拥有Book

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

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject
@property (nonatomic,copy) NSString *message;
@property (nonatomic,copy) NSString *name;
@property (nonatomic,retain) Book *book;
@end
NS_ASSUME_NONNULL_END

设定MRC
让他过世

@interface Person()
//@property (nonatomic,copy) NSString *message;
@end
@implementation Person
// 只要这个方法被执行,就代表这个对象被回收了
- (void)dealloc
{
    NSLog(@"名字叫做%@的人去了",self.name);
    [self.name release];
    [self.book release];
    [super dealloc];
}
- (void)sayHi{
    NSLog(@"Hi");
}
@end

在这之後,我想让书友拥有者这个属性。
我import Person 到 Book里面。
然後加入一个property。

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

NS_ASSUME_NONNULL_BEGIN

@interface Book : NSObject

/// 书名
@property(nonatomic,retain)NSString *name;

/// 作者名称
@property(nonatomic,retain)NSString *authorName;

@property(nonatomic,retain)Person *owner;

/// 传播知识
- (void)castKnowledge;
@end

NS_ASSUME_NONNULL_END

奇怪的是预编译居然报错了。

这是什麽情况呢?
当两个文件相互包含的时候,当Person.h 而 Book.h 包含 Person.h这个时候,就会出现循环引用的问题。就会造成无限递回的问题,而导致无法编译通过。

graph LR;
Person --> Book;
Book --> Person;

解决方法:

其中一边不要使用#import引入对方的头文件,而是使用@class 类名;
来标注这是一个类,这样子就可以在不引入对方头文件的情况下,告诉编译器这是一个类。

在.m 文件中再import对方的头文件,就可以使用了。

@class与#import的区别

#import是将指定的文件内容拷贝到写指令的地方。
@class 并不会拷贝任何内容。只是告诉编译器这只是一个类别,这样编译才可以知道这是一个类。

相互引用的正确姿势

在 Person.h 加入了 @class Book

#import <Foundation/Foundation.h>
@class Book;
NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject
@property (nonatomic,copy) NSString *message;
@property (nonatomic,copy) NSString *name;
@property (nonatomic,retain) Book *book;
@end
NS_ASSUME_NONNULL_END

这样的结果很好,苏东坡去了,书也烧了

但是有个问题

当我在写这段code的时候,没有提示。为什麽呢?
因为你至始至终都没有引入Book的头文件,这样怎麽办呢?
在Person.m里面import Book.h


<<:  ​修复:隐藏受保护的作业系统档案选项在资料夹选项中丢失

>>:  AI - 海关图图片侦测判别

【Tableau Desktop入门】免费2小时基础操作体验

一、Tableau 是什麽 简单来说,Tableau是一个任何专业背景、任何年纪都可以学得会的大数据...

[Day3] 自我必备进化力:找到一面镜子

自信心溃堤 因为没有想像,所以没有了信心 当只有自己,自己就是自己的天花板,我之前的工作习惯是,遇到...

.NET Core API 产生 server-side 验证码

前言 因为正在开发的系统是内部类型,希望只是简单建立server-side的验证码机制就好,所以就不...

DAY29 Aidea专案实作-AOI瑕疵检测(4/4)

经过不懈的努力!我们终於来到此次专案时做的最後一个章节,前三个部分我们已经算是达成任务,成功训练出一...

[2021铁人赛 Day24] Forensics 监识学题目 01

小勘误: 前几天提到我们会把六大类都至少做过一题,但是 picoCTF 的 Misc 类 -- U...