ObjectiveC单例

基于ObjectiveC开发的Socket通讯动态库 本文通过介绍用ObjectiveC(以下简称OC)语言开发dylib(动态库),以TCP/IP客户端通信为实例讲解(含源码),掌握对OC语言TCP/IP客户端通信的开发。 阅读详情
其实对于单例,在程序开发中非常的常见。
最近我也对单例进行了一些更细致的研究。
在我的程序中,单例一般是这么去写的:
+ (DataSource *)shareInstance
{
    static DataSource *instance = nil;
    if (instance == nil)
    {
        instance = [[DataSource alloc] init];
    }
    return instance;
}


在我做过的十几个软件中,一直都是这么去写的。
但是在我前段时间看书的过程中,发现跟书中的例子不太一样,所以做了一下研究。


发现,这样的单例是不可靠的。因为如果开发者一直调用 [DataSource shareInstance] 当然没有问题, 但是如果有人调用 [ DataSource alloc] 这样的方法,就会出现多个对象。
所以,我们需要实现“严格”意义的单例。


需要克服两个障碍:
1. 发起调用的对象不能以其他分配方式实例化单例对象。
2.对单例对象实例化的限制应该与引用计数内存模型共存。


下面我们看一下官方给出的单例模式的例子


static MyGizmoClass *sharedGizmoManager = nil;  
  
+ (MyGizmoClass*)sharedManager  
{  
    if (sharedGizmoManager == nil) {  
        sharedGizmoManager = [[super allocWithZone:NULL] init];  
    }  
    return sharedGizmoManager;  
}  
  
+ (id)allocWithZone:(NSZone *)zone  
{  
    return [[self sharedManager] retain];  
}  
  
- (id)copyWithZone:(NSZone *)zone  
{  
    return self;  
}  
  
- (id)retain  
{  
    return self;  
}  
  
- (NSUInteger)retainCount  
{  
    return NSUIntegerMax;  //denotes an object that cannot be released  
}  
  
- (void)release  
{  
    //do nothing  
}  
  
- (id)autorelease  
{  
    return self;  
}


他的方式是重写release,retain,retainCount,autoRelease,allocWithZone和copyWithZone等方法。
1 重写allocWithZone和copyWithZone的目的是外部在多次调用alloc的时候,内部能够确保对象只创建了一次。
2 重写release、retain、autorelease、retainCount避免单件对象被外部释放。


两个缺点:
A 隐藏了在对象生命周期管理时出现的bug。
    对对象的引用出错的原因必然是程序本身的错误,隐藏对象的引用计数错误就是隐藏了应用程序的错误。
    从工程角度上讲,崩溃要比程序的逻辑错误容易定位。
    解决方法:建议在release、retain、autorelease里面做一些内部的调用次数监控,一旦发现外部调用不平衡就发出警告。
B 对象可以被多次init。
    多次调用init导致错误的可能性还是有的,这种错误包括重复加载某些资源降低性能。
    解决方法:重写init并在内部判重就可以了。
C 多线程安全
    解决方法:在sharedManager中加入同步代码块,代码:


+ (MyGizmoClass*)sharedManager  
{  
    @synchronized(self) {  
        if (sharedGizmoManager == nil) {  
            sharedGizmoManager = [[super allocWithZone:NULL] init];  
        }  
    }  
    return sharedGizmoManager;  
}  
基于ObjectiveC开发的TCP/IP客户端通讯命令行程序 本文通过介绍用ObjectiveC(以下简称OC)语言开发command line tool(命令行程序),以TCP/IP客户端通信为实例讲解(含源码),掌握对OC语言TCP/IP客户端通信的开发。 阅读详情

相关推荐

Objective C 单例模式设计源码

顾名思义,单例模式的特点就是保证一个类仅有一个实例。因为这个模式只和一个类有关,没有类与类之间的关系,所有就不给出图示了。那么还是先说一下基本的定义。 单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。平时,我们常用单例模式的地方通常是多线程。 因为Objective C传承了Smalltalk语言,所以在Objective C中实现单例模式和C++和C#以及Java都不太一样。因为要保证类型对象的单一性,所以就要考虑Objective C在实例化对象时候的各种方式。因为在Objective C中创建的各个类型都继承自NSObject类型,所以我们需要考虑NSObject类型里实例化的方法,下面让我们展开来说。 在Objective C的实例化对象的方式主要有三种,分别如下: obj = [NSObject new]; obj = [[NSObject alloc]init]; obj = [[NSObject allocWithZone]init]; NSObject类参考文档里记录第三种方法是因为历史原因遗留下来的,在当前的Objective C中已经不再使用,所以我们就不考虑这种方式了。下面让我们主要看一下前两种方式。 第一种方式,用new方法初始化其实是第二种方式的总和,当调用new方法时,其实是先调用了alloc方法进行isa(is a pointer)操作,创建指针,指向内存中的数据结构,紧接着调用了init方法对数据进行初始化,NSObject类参考文档里也有具体的说明,大家也可以查看文档,具体实现方式随后我会用代码向大家进行展示。 第二种方式看起来就很明确了,先调用alloc创建指针指向内存中的数据结构,再调用init方法初始化数据。这里需要注意的是,init方法只是起到了初始化数据的作用,其实也可以自定义初始化方法,即完全可以自定义一个普通返回NSObject类型的方法来代替init方法,即init方法是可以随意被代替的。只不过NSObject类型中new方法默认会调用init方法而已,init方法可以看作是NSObject类型的默认构造函数。 所以综上所述,其实只有alloc方法是每次必须调用的方法,那么我们只要控制住alloc方法,对此方法进行覆盖就可以保证类型对象的单一性了。好了,说了这么多,让我们看看如何实现吧。

【Objective-C】单例模式

对单例模式的一般实现方法、苹果官方提供的GCD实现方法进行了学习

XY_Mckevince的博客 954

小红书UID泄露风险揭秘:如何防止你的手机号被社工库关联(附防护指南)

本文揭示了小红书UID泄露的严重风险,详细解析了UID与手机号关联后被社工库利用的完整链条。通过分析黑产的数据整合技术,提供从基础到进阶的防护策略,包括密码管理、账号隔离和应急响应措施,帮助用户有效防范个人信息泄露风险。

ol789012345的博客 1506

Objective-C实现单例

单例,顾名思义,即有且只有一个实例。那么创建函数(sharedInstance)被多次调用,以及多线程场景下,如何保证这一点? 使用GCD技术: +(instancetype)sharedInstance { static ClassName* _sharedInstance = nil; static dispatch_once_t onceToken; dispa...

auspark的专栏 636

AI Agent ReAct架构设计模型剖析

ReAct通过"思考-行动-观察"循环运作:智能体先进行自然语言推理,再调用外部工具执行行动,观察结果后继续推理直至解决问题。这种架构提高了透明度和准确性,减少幻觉风险,使LLM能主动分解任务并利用外部数据源。实现关键在于精心设计的提示模板,引导LLM按结构化格式响应,而非依赖模型固有能力。

weixin_43939320的博客 1250

避坑指南:Dify+Docker+Ollama离线部署实战与疑难解析

本文详细解析了在国产化系统(如银河麒麟V10)内网环境中,如何从零开始离线部署Dify、Docker与Ollama的全栈AI应用开发平台。文章重点拆解了Docker安装中的“没有Release文件”和“GPG密钥错误”等典型报错解决方案,并提供了Ollama离线模型导入与Dify连接配置的完整实战指南,旨在帮助开发者高效完成本地部署,避开常见陷阱。

dd012的博客 464

Objective-C 单例

/** * Student.h文件 * */ #import @interface Student : NSObject //在要设计成单例类的 .h 文件声明一个构造的单例方法 + (Student *)sharedStudent; @end /** * Student.m 文件 */ #import "Student.h" //声明一个静态实例对象 只能执行一次 stat

zyx 628

【python股票价格预测】基于LSTM(长短期记忆网络)的股票价格预测(附python代码)

【python股票价格预测】基于LSTM(长短期记忆网络)的股票价格预测(附python代码)

k8291121的博客 1012

Object-c之单例模式

Objective-c 单例设计模式(Singleton) 一、什么是单例模式:(Singleton) 单例模式的意图是是的类的对象成为系统中唯一的实例,提供一个访问点,供客户类共享资源。二、什么情况下使用单例? 1、类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。 2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户

图解AI 4367

GameFramework专栏目录

本专栏是专门介绍GameFramework框架的,持续更新中,如有疑问可留言,24小时内回复。

TxNet 4726

MFC中的CMFCToolBar:自定义按钮提示消息

通过以上步骤,您可以在MFC应用程序中使用CMFCToolBar创建自定义按钮,并设置按钮的提示消息。通过以上步骤,您可以在MFC应用程序中使用CMFCToolBar创建自定义按钮,并设置按钮的提示消息。通过上述代码,您可以在MFC应用程序中添加一个名为"ID_BUTTON_CUSTOM"的自定义按钮,并将其提示消息设置为"自定义提示消息"。通过上述代码,您可以在MFC应用程序中添加一个名为"ID_BUTTON_CUSTOM"的自定义按钮,并将其提示消息设置为"自定义提示消息"。

PixelInk的博客 1084

Object-C中单例的特性和实现

一句话介绍单例:整个程序中,无论什么时候无论在哪个类中创建一个对象,创建时取到的对象永远是同一个对象。 单例的特性: 1.由于在不同位置创建的对象返回的都是同一个对象,因此,单例模式可以作为整个程序的一个共享对象,任何时候任何模块都可以操作访问该单例对象的属性。 2.有人说,宏定义也可以全局共享使用。但是单例还有一个重要的特性,就是在程序运行过程中,可以根据实际需求修改单例对象的属性,而宏定义一旦定义后,整个程序运行过程中是无法修改的。 单例的实现思路: Object-C中创建一个对象的时候会调用

JustinZYP的博客 459

龙腾CMS downloadFile接口任意文件读取漏洞复现 [附POC]

大连网龙网络科技有限公司专注于在信息科技领域中向客户提供商业解决方案,是专业的互联网服务解决方案提供商和网络营销服务专家,为用户提供一体化的网络营销整体解决方案,龙腾CMS downloadFile接口存在任意文件读取漏洞。

薛定谔嘚喵博客 720

单例在ObjectiveC中的正确打开方式

我们写第一个单例

Coder Bruce 577

华为OD机试 双机位A卷 - 流量波峰 (C++ & Python & JAVA & JS & GO)

华为OD机试双机位A卷 流量波峰,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1377

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

如何创建完整版单例

1.声明单例对象 在.h文件 +(SingleCase *)sharedSingleCase; 2.实现单例 在.m文件 SingleCase * singleCase = nil; +(SingleCase *)sharedSingleCase{ static dispatch_once_t onceToken; disp...

110

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

dispatch_once单例初始化

static GHCache *instance = nil; /** * 单例,静态初始化方法 * * @return 返回一个单例 */ + (GHCache*)shareCache{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instanc...

weixin_34097242的博客 100

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

objective-c 单例

单例是一种类,该类只能实例化一个对象。 尽管这是单例的实际定义,但在Foundation框架中不一定是这样。比如NSFileManger和NSNotificationCenter,分别通过它们的类方法defaultManager和defaultCenter获取。尽管不是严格意义的单例,这些类方法返回一个可以在应用的所有代码中访问到的类的共享实例。在本文中我们也会采用该方...

aa4197435的博客 140

利用dispatch_once创建单例

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33852020的博客 74

IOS开发之dispatch_once创建单例

转载自:http://blog.youkuaiyun.com/sanpintian/article/details/8140671 单例是一种类,该类只能在第一次用的时候实例化一个对象,后期直接调用此对象(有点共享的意思)。在Foundation框架中比如NSFileManger和NSNotificationCenter,分别通过它们的类方法defaultManager和defaultC...

weixin_34419326的博客 68

Objective-C设计模式——单例Singleton(对象创建)

单例 和其它语言的单例产不多,可以说是最简单的一种设计模式了。但是有几个点需要注意下,单例就是一个类只有一个实例。 所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为private。但是OC中的函数并没有限定符,所以我们需要用一些小技巧来屏蔽这一点。 应用场景 类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。 这个唯一的实例只能通过类的子...

weixin_30445169的博客 97

objective c单例设计模式

单例设计模式 什么是单例? 其实就是C中的全局变量,在整个生命周期中,该对象只有一份存在内存中,可以在多个对象之间共享数据。 典型的单例写法: static id sharedMyManager; + (id) sharedThemeManager {      if (sharedMyManager == nil)      {               sharedMyMa

Stephan14的专栏 837

ios object-c 实现Singleton(单例)模式

Singleton模式经常来做应用程序级别的共享资源控制, 应该说这个模式的使用频率非常高, 现在来看看在Objective-C里面的实现方法.要实现一个Singleton Class, 至少需要做以下四个步骤:1. 为Singleton Object实现一个静态实例, 初始化, 然后设置成nil.2. 实现一个实例构造方法(通常命名为 sharedInstance 或者 sharedM...

diezhi9415的博客 149

ObjectiveC基础——对象关系

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-一、概述对象与对象的关系可以分为:组合关系、依赖关系、关联关系。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。耦合度是指对模块间关联程度的度量。耦合的强弱取决与模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。耦合度越强,同时表明其独立性越差。低耦合:当修

u010201701的博客 576

HappyDNS-ObjectiveC 使用指南

HappyDNS-ObjectiveC 使用指南 项目介绍 HappyDNS-ObjectiveC 是一个面向Objective-C的DNS库,它允许开发者调用系统底层的DNS解析库,并支持集成多种DNS解析方案,包括但不限于使用114等传统第三方DNS服务,DoH(DNS over HTTPS)协议的解析,以及HTTPDNS如Dnspod的服务。此外,该库提供了灵活的hosts配置选项,增强了应...

gitblog_00962的博客 1242

元组中数组_ObjectiveC的元组实现(JDTuple)

引言有没有觉得OC的数组和字典使用起来特别繁琐?我们在使用字典或数组时,总是需要判断数组越界,判断数据是否为空,判断数据类型。有没有觉得定义多参数函数的时候特别杂乱无章?有没有觉得Swift的元组使用起来特别顺心?这些问题其实都源于OC是一门比较古老的语言,早期设计时缺少一个足够灵活,足够好用的数据封装工具。试想一下,假如OC也有一个元组类,这个类可以封装任意数据,包装时也无须关注数据的...

weixin_35282782的博客 745
上一篇: #import与@class的区别
下一篇: 将父类指针赋给self的原因理解
bart2011
博客等级 码龄16年 10粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值