热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ObjectiveC分析之一

Objective-C分析,再深入了解一下,发现还是有很多不懂得地方,有些方法属性从来都没有用过。官方文档确实很详细。基础Objective-C模块API定义了Objective-

Objective-C分析,再深入了解一下,发现还是有很多不懂得地方,有些方法属性从来都没有用过。官方文档确实很详细。

基础

  • Objective-C模块API定义了Objective-C语言的基础。 这些API包括:类型,如NSObject类和NSObject协议,提供大多数Objective-C类的根功能构成Objective-C运行时的函数和数据结构,为Objective-C语言的动态属性提供支持。

  • 类 Classes

    • NSObject
    • Object
    • Protocol
  • 协议 Protocols

    • NSObject
  • 相关数据

    • Objective-C Runtime
    • Objective-C Structures
    • Objective-C Enumerations
    • Objective-C Constants
    • Objective-C Functions
    • Objective-C Data Types

NSObject

  • 大多数Objective-C类层次结构的根类,子类继承了运行时系统的基本接口以及拥有Objective-C对象的基本能力。
  • 《Objective-C分析之一》

初始化类

  • initialize

    • 这个方法在一个类中会调用一次,父类先调用,子类后调用。(Initializes the class before it receives its first message.)
  • load

    • 每当将类或类添加到Objective-C运行时时调用;实现此方法在加载时执行类特定的行为。
    • 而且是一个类所有方法中第一个调用的方法。只要这个类包含在项目中就会调用这个方法。
    • 父类先调用load,子类再调用。父类先调用,分类再调用。
    • 注意:桥接到Objective-C的Swift类的加载方法的自定义实现不会自动调用。

create,copy,dealloc对象

  • alloc
    • Returns a new instance of the receiving class. 返回一个新的类对象
    • 分配数据结构以及内存空间
    • alloc 方法不可单独用,要配合init方法完成初始化流程。 TheClass *newObject = [[TheClass alloc] init];
  • allocWithZone:
    • 和alloc 方法功能一样,是因为历史原因而存在。alloc方法会唤醒allocWithZone方法。
    • 参数zone可以忽略,因为Objective-C不再使用内存块(memory zones)。
  • init
    • init 只是在NSObject中进行了声明,并没有实现。
    • 由子类实现,在内存被分配之后立即初始化一个新的对象。如果创建失败就返回nil。
    • init 不应该单独出现,应该和alloc和allocWithZone一起出现。
    • 在子类中重写init时应该调用父类的init 方法。

- (instancetype)init {
self = [super init];
if (self) {
// Initialize self
}
return self;
}

  • copy

    • copyWithZone: 的便捷方法
    • 拷贝构造函数,至于深拷贝还是浅拷贝由自己实现
    • 遵守NSCopying协议的对象通过copyWithZone:方法返回的对象。
    • NSObject对象本身不遵守NSCopying协议,必须由子类遵守NSCopying协议并实现copyWithZone:方法才能使用copy方法,否则会有异常。
  • copyWithZone:

    • + (id)copyWithZone:(struct _NSZone *)zone 参数zone忽略。
    • 拷贝构造函数,至于深拷贝还是浅拷贝由自己实现。
    • 只要遵守NSCopying协议就可以实现这两个 copy方法实现对象拷贝操作。
  • mutableCopy

    • mutableCopyWithZone: 的便捷方法
    • 遵守NSMutableCopying协议的对象通过mutableCopyWithZone:方法返回的对象。
    • 要使用这个方法必须由子类遵守NSMutableCopying协议并实现mutableCopyWithZone:方法才能使用mutableCopy方法,否则会有异常。
  • mutableCopyWithZone:

    • + (id)mutableCopyWithZone:(struct _NSZone *)zone; 参数zone忽略。
    • 只要遵守NSMutableCopying协议就可以实现这两个mutableCopy方法实现对象拷贝操作。
  • dealloc

    • 类似C++析构函数,释放内存空间
    • 可以重新这个方法释放自己定义的对象等。不需要调用 [super dealloc],而且不能直接调用这个方法,它会自动由运行时调用。
    • 不用ARC是要自己控制对象的引用计数,在dealloc中进行release
  • new

    • 便捷方法,相当于调用[[Class alloc] init]

方法

  • + class

    • 返回类自身
  • + (Class)superclass;

    • 返回父类对象
  • + (BOOL)isSubclassOfClass:(Class)aClass;

    • 是否是某个类的子类
  • + (BOOL)instancesRespondToSelector:(SEL)aSelector;

    • 判断类是否支持相应某个方法,和- respondsToSelector:方法一样
  • + (BOOL)conformsToProtocol:(Protocol *)protocol;

    • 判断对象是否遵守指定协议,协议可以继承,那么父类的协议中的方法有没有在子类中实现要自己检查。
  • - (IMP)methodForSelector:(SEL)aSelector;

    • 返回方法地址,参数不能为空,必要时使用respondsToSelector:方法进行判断。
    • 如果调用着是一个类,那么参数必须是类方法,是对象,参数必须是对象方法。

if ([self respondsToSelector:@selector(test)]) {
IMP imp = [self methodForSelector:@selector(test)];

NSLog(@"对象方法imp:%x",imp);
} if ([AppDelegate respondsToSelector:@selector(test1)]) {
IMP imp = [AppDelegate methodForSelector:@selector(test1)];

NSLog(@"类方法imp:%x",imp);
}
- (void)test {
NSLog(@"test");
}
+ (void)test1 {
NSLog(@"test1");
}

  • + (IMP)instanceMethodForSelector:(SEL)aSelector;
    • 返回对象方法的地址

if ([AppDelegate instancesRespondToSelector:@selector(test)]) {
IMP imp = [AppDelegate instanceMethodForSelector:@selector(test)];

NSLog(@"对象方法imp:%x",imp);
}

  • + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector;
    • 返回对象方法的方法签名

NSMethodSignature *methodSignature = [AppDelegate instanceMethodSignatureForSelector:@selector(test)];
NSLog(@"参数%zd个,参数总长度:%zd,返回类型:%s,返回长度:%zd",methodSignature.numberOfArguments,methodSignature.frameLength,methodSignature.methodReturnType,methodSignature.methodReturnLength);
// 参数2个,参数总长度:224,返回类型:v,返回长度:0 methodSignature = [AppDelegate instanceMethodSignatureForSelector:@selector(testWith:number:)];
NSLog(@"参数%zd个,参数总长度:%zd,返回类型:%s,返回长度:%zd",methodSignature.numberOfArguments,methodSignature.frameLength,methodSignature.methodReturnType,methodSignature.methodReturnLength);
// 参数4个,参数总长度:224,返回类型:@,返回长度:8
if([methodSignature isOneway]) {
NSLog(@"异步");
}
- (void)test {
NSLog(@"test");
}
- (NSString *)testWith:(NSString *)one number:(NSInteger )num {
NSLog(@"testWith:%@ number:%zd",one,num);
return @"";
}

/* NSMethodSignature.h
Copyright (c) 1994-2016, Apple Inc. All rights reserved.
*/
#import
NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available")
@interface NSMethodSignature : NSObject {
@private
void *_private;
void *_reserved[6];
}
/// 创建对象
+ (nullable NSMethodSignature *)signatureWithObjCTypes:(const char *)types;
/// 参数个数,至少两个,一个self,一个_cmd
@property (readonly) NSUInteger numberOfArguments;
/// 获取参数类型,self -> id ,_cmd -> IMP
- (const char *)getArgumentTypeAtIndex:(NSUInteger)idx NS_RETURNS_INNER_POINTER;
/// 参数总长度,在内存堆栈上的大小,和硬件架构有关
@property (readonly) NSUInteger frameLength;
// 调用着是否是异步的
- (BOOL)isOneway;
/// 返回值类型
@property (readonly) const char *methodReturnType NS_RETURNS_INNER_POINTER;
/// 返回值长度,内存堆栈上的长度
@property (readonly) NSUInteger methodReturnLength;
@end
NS_ASSUME_NONNULL_END

  • - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
    • 和上面方法类似,还可以生成类方法的方法签名。
    • 另外在消息转发中,如果遵守了协议,但是没有直接实现协议方法,可以重写这个方法来返回正确的方法签名

methodSignature = [self methodSignatureForSelector:@selector(testWith:number:)];
NSLog(@"对象方法参数%zd个,参数总长度:%zd,返回类型:%s,返回长度:%zd",methodSignature.numberOfArguments,methodSignature.frameLength,methodSignature.methodReturnType,methodSignature.methodReturnLength);
// 参数2个,参数总长度:224,返回类型:v,返回长度:0
if([methodSignature isOneway]) {
NSLog(@"异步");
} methodSignature = [AppDelegate methodSignatureForSelector:@selector(test1)];
NSLog(@"类方法参数%zd个,参数总长度:%zd,返回类型:%s,返回长度:%zd",methodSignature.numberOfArguments,methodSignature.frameLength,methodSignature.methodReturnType,methodSignature.methodReturnLength);
// 参数2个,参数总长度:224,返回类型:v,返回长度:0
if([methodSignature isOneway]) {
NSLog(@"异步");
}
- (NSString *)testWith:(NSString *)one number:(NSInteger )num {
NSLog(@"testWith:%@ number:%zd",one,num);
return @"";
}
+ (void)test1 {
NSLog(@"test1");
}

  • + (NSString *)description;
    • 打印对象信息,默认只打印类名,可以重写这个方法打印更加详细的信息。
    • NSLog(@"self:%@",[self description]); //
  • @property(readonly, retain) id autoContentAccessingProxy;
    • 返回遵守NSDiscardableContent协议的对象,
    • 具体用法参看 http://southpeak.github.io/2015/02/11/cocoa-foundation-nscache/


/*********** Discardable Content ***********/
@protocol NSDiscardableContent
@required
- (BOOL)beginContentAccess; // count + 1
- (void)endContentAccess; // count - 1
- (void)discardContentIfPossible; // 丢弃内存数据
- (BOOL)isContentDiscarded; // 是否丢弃内存数据
@end
@interface NSObject (NSDiscardableContentProxy)
// 返回遵守NSDiscardableContent协议的代理
@property (readonly, retain) id autoContentAccessingProxy NS_AVAILABLE(10_6, 4_0);
@end

  • NSDiscardableContent是一个协议,实现这个协议的目的是为了让我们的对象在不被使用时,可以将其丢弃,以让程序占用更少的内存。
  • 使用类似引用计数的方式,对象的count动态+1,-1,当count为0时,对象会被内存回收。

接下来继续往下看


推荐阅读
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 在看PHP扩展开发时,看到一处关于PHP函数返回值的问题。当定义了一个函数,而这个函数拥有返回值,在用户使用时,并没有使用返回值,zend引擎可以实现报错,这是如何实现的,怎么个原 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • jsappsugar,基于,js,语法,定义 ... [详细]
author-avatar
wxxc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有