!!!Obj-C 2.0 -- Chapter 5 Categories and Extensions

本文深入探讨了如何使用Objective-C中的类别(category)特性向现有类添加方法,包括方法的声明与定义、类别的命名约定、如何在类中使用类别以及类别与扩展的区别。此外,还解释了类别不能添加实例变量,以及如何通过导入文件来实现对特定类的方法扩展。

A category allows you to add methods to an existing class -- even to one to which you don't have the source.

5.1 Adding Methods to Classes

You can add methods to a class by declaring them in an interface file under a category name and defining them in an implementation file under the same name. The category name indicates that the methods are additions to a class declared elsewhere, not a new class.

You cannot use a category to add additional instance variables to a class.

The methods the category adds to the class are inherited by all the class's subclasses, just like other methods.

The declaration of a category interface looks similar to a class declaration -- except the category name is listed within parentheses after the class name and the superclass isn't mentioned. Unless its methods don't access any instance variables of the class, the category must import the interface file for the class it extend:

#import "ClassName.h"

@interface ClassName ( CategoryName )
// method declarations
@end
For Category files, a common naming convention is that the base file name of the category is the name of the class the category extends followed by "+" followed by the name of the category: (ClassName+CategoryName.m):

#import "ClassName+CategoryName.h"

@implementation ClassNmae ( CategoryName )
// method definitions
@end 
All instance variables within the scope of the class are also within the scope of the category. That includes all instance variables declared by the class, even ones declared @private.

5.2 How you Use Categories

Although the language currently allows you to use a category to override methods the class inherits, or even methods declared in the class interface, you are strongly discouraged from using this functionality.

5.4 Extensions

Class extensions are like "anonymous" categories, except that the methods they declare must be implemented in the main @implementation block for the corresponding class.

It is common for a class to have a publicly declared API and to then have additional API declared privately for use solely by the class or the framework within which the class resides (E.G. readwrite/readonly property attributes).

// Category implementation, can compile successfully
@interface MyObject : NSObject
{
    NSNumber *number;
}
- (NSNumber *) number;
@end

@interface MyObject (Setter)     // category
- (void)setNumber: (NSNumber *)newNumber;
@end

@implementation MyObject
-( NSNumber *) number {
    return number;
}
@end

This is no implementation of the setNumber: method, if it's invoked, it will generate error.

// Category implementation, can compile successfully
@interface MyObject : NSObject
{
    NSNumber *number;
}
- (NSNumber *) number;
@end

@interface MyObject ()     // extension
- (void)setNumber: (NSNumber *)newNumber;
@end

@implementation MyObject
-( NSNumber *) number {
    return number;
}
-(void)setNumber:(NSNumber *)newNumber{
    number = newNumber;
}
@end

This is no implementation of the setNumber: method, if it's invoked, it will generate error.

Note:

1. No name is given in theparentheses in the second @interface block.

2. The implementation of thesetNumber: method appears within the main @implementation block for the class.

For one class, we canhave multiple categories, but we can only have one extension.

Extension can addinstance variable and override property!


<think>我们分析条件:`if (!download_diag_obj->numberOfConnections || download_diag_obj->numberOfConnections > download_diag_obj->downloadDiagnosticMaxConnections)` 这个条件由两个子条件通过逻辑或(OR)连接组成,判断的是连接数参数是否有效。 具体拆解: 1. `!download_diag_obj->numberOfConnections` - 含义:检查`numberOfConnections`是否为0(或假值)。在C语言中,数值为0时逻辑判断为假,取非则为真;非0为真,取非为假。 - 作用:判断连接数是否未设置(即为0)或者设置为0(因为0个连接没有意义)。 2. `download_diag_obj->numberOfConnections > download_diag_obj->downloadDiagnosticMaxConnections` - 含义:检查设置的连接数是否超过了最大允许连接数(`downloadDiagnosticMaxConnections`)。 因此,整个条件判断的是:如果连接数未设置(为0)或者设置的连接数超过了允许的最大值,则条件成立,进入错误处理分支。 在错误处理分支中: - 记录错误日志(TR143_ERROR) - 将配置中的连接数(`pCfg->num_of_conn`)设置为默认值(`download_diag_obj->X_TP_DownDefConns`) - 同时,修正源数据(`download_diag_obj->numberOfConnections`)为默认值,以确保后续使用的一致性。 如果条件不成立(即连接数有效,非0且不超过最大值),则直接使用设置的连接数。 所以,这个条件的作用是确保连接数在有效范围内(1到最大值之间),否则使用默认值并修正源数据。 §§相关问题§§ 1. 为什么在条件中要检查`numberOfConnections`为0(即`!download_diag_obj->numberOfConnections`)?在实际应用中,设置连接数为0可能表示什么? 2. 如果`downloadDiagnosticMaxConnections`的值被错误设置为0,这个条件判断会有什么后果? 3. 在错误处理分支中,为什么要同时修改配置结构体(`pCfg->num_of_conn`)和源数据对象(`download_diag_obj->numberOfConnections`)的值? 4. 这个条件判断是否考虑到了负数连接数的情况?如果传入负数会如何处理? 5. 在TR369模式下,同样的有效性判断使用了参数结构体`pParm`而非`download_diag_obj`,这是为什么? </think>以下是针对条件判断 `if (!download_diag_obj->numberOfConnections || download_diag_obj->numberOfConnections > download_diag_obj->downloadDiagnosticMaxConnections)` 的详细解析: ### 条件判断分析 该条件由两个子条件通过逻辑或(`||`)组合而成,用于验证连接数参数的有效性: #### 1. **第一子条件:`!download_diag_obj->numberOfConnections`** - **含义**:检测连接数是否为**无效值** - **具体判断**: - 当 `numberOfConnections` 等于 `0` 时成立(0 在布尔判断中为假,`!` 取反为真) - 当 `numberOfConnections` 为 `NULL` 时成立(指针类型的特殊判断) - **设计目的**: - 确保连接数配置不能为零(零连接无意义) - 防止未初始化的空指针导致程序崩溃 #### 2. **第二子条件:`numberOfConnections > downloadDiagnosticMaxConnections`** - **含义**:检测连接数是否**超过系统上限** - **具体判断**: - 当设置的连接数大于系统允许的最大连接数时成立 - **设计目的**: - 防止资源过载(如内存耗尽或网络拥塞) - 确保诊断测试在安全范围内运行 #### 3. **组合逻辑:逻辑或(`||`)** - **触发条件**:任意一个子条件成立即进入错误处理分支 - **错误处理内容**: ```c TR143_ERROR(...); // 记录错误日志 pCfg->num_of_conn = 默认值; // 使用默认连接数 download_diag_obj->numberOfConnections = 默认值; // 修正源数据 ``` ### 设计意图图解 ```mermaid graph TD A[连接数检查] --> B{是否为0/NULL?} A --> C{是否超过最大值?} B -->|是| D[判定无效] C -->|是| D D --> E[记录错误日志] E --> F[使用默认值] F --> G[修正源数据] B -->|否| H[有效] C -->|否| H H --> I[使用原值] ``` ### 典型应用场景 1. **新设备初始化**: - `numberOfConnections` 默认为0 - 触发条件一 → 使用默认值10 2. **错误配置**: - 管理员误设连接数=1000 - 系统上限=500 → 触发条件二 → 自动修正为默认值 3. **空指针防护**: - 内存分配失败导致指针为NULL - 触发条件一 → 避免程序崩溃
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值