iOS中怎么判断可变和不可变的坑(更正版)
iOS中怎么判断可变和不可变的坑
怎么判断NSString和NSMutableString呢
看题
BOOL result = [@"" isKindOfClass:[NSMutableString class]];
// A:YES B:NO
送分题一看就选B的。然而正确答案却是A(这里提及下涉及的两个概念:类簇,工厂模式)
看控制台弄出来的结果
id str0 = [NSString alloc];//NSPlaceholderString->NSString
id str1 = [[NSString alloc] init];//__NSCFConstantString->__NSCFString->NSMutableString->NSString
id str3 = [NSString stringWithFormat:@""];//NSTaggedPointerString->NSString
id str4 = [NSMutableString alloc];//NSPlaceholderMutableString->NSMutableString->NSString
id str5 = [NSMutableString new];//__NSCFString->NSMutableString->NSString
字符串常量,也就是str1那种创建方式得到的类型是__NSCFConstantString并且明目张胆的是NSMutableString的子类。无论如何请勇敢的质疑苹果脑残的设计。并且后面的Array和Dictionary就不存在这种脑残的地方。我们无法知道到底黑盒子里有多少这种子类,根据倒推法:
所以现在判断一个字符串是可变的这么写就行了
BOOL isMutable = [str isMemberOfClass:NSClassFromString(@"__NSCFString")];//请注意是isMemberOfClass:这个方法不要用成isKindOfClass:
把Array的控制台结果也弄出来简单的看一下
NSArray* arr0 = [[NSArray alloc] init];//__NSArray0->NSArray
NSArray* arr1 = [NSArray arrayWithObject:@""];//__NSArrayI->NSArray
NSMutableArray* arr3 = [[NSMutableArray alloc] init];//__NSArrayM->NSMutableArray->NSArray
可以发现虽然NSArray也子嗣众多,但不会出现String那种近亲乱的情况。
判断Array是不可变的这么写就行了,不需要写字符串的类型
BOOL notMutable = [arr isKindOfClass:[NSArray class]]&&![arr isKindOfClass:[NSMutableArray class]];
NSDictionary的情况同NSArray。
转注出:原文
===========更正===========================
上面的方法在实际使用中被证明是错的,看如下两个方法
//在有的版本中执行结果如下
@().description;//__NSCFString->NSMutableString->NSString
[NSString stringWithFormat:@"123%d",]//__NSCFString->NSMutableString->NSString
就是说这两种情况从外部审查类型来看,根本和[NSMutableString new]的效果是一样的,而且是响应下面的方法的
[xxx respondsToSelector:@selector(appendFormat:)];
但是实际的情况是一调用就崩溃了。不听老人言吃亏在眼前,真的是最打脸的道理最朴素。一个不开源的东西,我们就是喜欢在外面赌博。
思考了很久我发现了解决之道,大道果然至简:我不知道它怎么实现的,但是苹果知道……
所以:
id copyed = [xxx copy];
if(copyed == xxx){
@"不可变".nslog();
}else{
@"可变的".nslog();
}
如果一个对象是可变的,copy之后会返回新对象,我们比较这两个指针就可以了。里面是如何实现的,我们不再关心。
iOS中怎么判断可变和不可变的坑(更正版)的更多相关文章
- iOS 中如何判断当前是2G/3G/4G/5G/WiFi
5G 什么的,还得等苹果API更新啊,不过将来还是这个处理过程就是了. 关于判断当前的网络环境是2G/3G/4G,这个问题以前经常看到,最近在一工程里看到了如果判断的API.而在撸WebRTC音视频通 ...
- IOS中如何判断APP是否安装后首次运行或升级后首次运行
对于是否为首次安装的App可以使用如下方法来判断 [[NSUserDefaults standardUserDefaults] boolForKey:@"firstLaunch"] ...
- ios中怎么样判断路径最后的后缀名称
使用hasSuffix属性即可 例如 [photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"]
- IOS 中runtime 不可变数组__NSArray0 和__NSArrayI
IOS 中runtime 不可变数组__NSArray0 和__NSArrayI 大家可能都遇到过项目中不可变数组避免数组越界的处理:runtime,然而有时候并不能解决所有的问题,因为类簇不一样 # ...
- python中的可变与不可变对象
Python中的可变对象和不可变对象 什么是可变/不可变对象 不可变对象,该对象所指向的内存中的值不能被改变.当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一 ...
- Java中的String为什么是不可变的?
转载:http://blog.csdn.net/zhangjg_blog/article/details/18319521 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那 ...
- php学习笔记5--php中的可变变量,可变函数及匿名函数
可变变量指的是:将一个变量的值再次当做一个变量名从而得到另外一个变量的值.如:$name = 'dqrcsc';$myname = 'name'; //$myname的值碰巧是另一个变量的变量名ech ...
- Java基础知识强化101:Java 中的 String对象真的不可变吗 ?
1. 什么是不可变对象? 众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对 ...
- IOS开发中如何判断程序第一次启动(根据判断结果决定是否显示新手操作引导)
IOS开发中如何判断程序第一次启动 在软件下载安装完成后,第一次启动往往需要显示一个新手操作引导,来告诉用户怎么操作这个app,这就需要在程序一开始运行就判断程序是否第一次启动,如果是,则显示新手操作 ...
随机推荐
- Angular面试题三
十六.一个 angular 应用应当如何良好地分层? 目录结构的划分 1.对于小型项目,可以按照文件类型组织,比如: css Js { controllers models services ...
- QQ 聊天机器人小薇 2.1.0 发布!
本次发布加入了支持茉莉机器人,并且更容易搭建开发环境,在线显示登录二维码~ 简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动: 监听多个 QQ 群消息 ...
- 命令行下运行 java someClass.class出现 “错误:找不到或无法加载主类someClass ” 的解决方案
假设在C:\Java\code\目录下建立了如下 Test.java文件: package code; public class Test { public static void main(Stri ...
- VB.NET Syntax Tips
Difference Between C# and VB.NET Namespace VB.NET [Class Namespace in IL]=[Root Namespace].[Namespac ...
- Linux常用命令(三)————创建+删除+设置权限
1. mkdir mkdir [选项] DirName 命令中的[选项]: -m 用于对新建目录设置存取权限,也可以用 chmod 命令进行设置. -p 需要时创建上层文件夹(或目录), ...
- Visual Studio 2017RC 版本相关资料
Visual Studio 2017 RC版本说明 1.社区版 Visual Studio Community 2017 RC Visual Studio Community 2017 RC 是针对个 ...
- ASP.NET Core 上传多文件 超简单教程
示例源码下载地址 https://qcloud.coding.net/api/project/3915794/files/4463836/download 项目地址 https://dev.tence ...
- 骑士周游问题跳马问题C#实现(附带WPF工程代码)
骑士周游问题,也叫跳马问题. 问题描述: 将马随机放在国际象棋的8×8棋盘的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部64个方格. 代码要求: 1,可以任意选定马在棋盘上 ...
- Git在eclipse中的配置
1:git在eclipse中的配置 windows - >preferences->team->git->configuration 点击add Entry key值:输入 u ...
- echarts柱状图,改变柱状颜色
在使用echarts产生的柱状图中,有时候自动产生的颜色大不如人意,可以通过以下参数进行修改. series : [ { name:'天数', type:'bar', stack: '天', data ...