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

tags: OC 30 day

创建一个类

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

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

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

propertyTypenameNSStringauthorNameNSStringcastKnowledgeparameterreturnTextvoidvoid

如何做到呢?

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

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface Book : NSObject/// 书名@property(nonatomic,retain)NSString *name;/// 作者名称@property(nonatomic,retain)NSString *authorName;/// 传播知识- (void)castKnowledge;@endNS_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;@endNS_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;@endNS_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;@endNS_ASSUME_NONNULL_END

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

但是有个问题

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


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章