19、构建第一个Cocoa应用与初始化方法详解

构建第一个Cocoa应用与初始化方法详解

1. 构建TahDoodle应用

在构建TahDoodle应用时,首先要确保滚动视图的大小和位置在窗口变化时能得到保证。当添加足够的约束后,滚动视图的支柱会变为蓝色。
- 操作步骤
1. 选择滚动视图,添加约束以保证其大小和位置。
2. 构建并运行应用,此时滚动视图会随窗口大小调整,但窗口变高时可能会覆盖按钮。
3. 为按钮添加自动布局约束,在文档大纲中选择“PushButton”,添加“pin the leading space to the superview”和“pin the bottom space to the superview”两个布局约束。再次构建并运行应用,滚动视图会随窗口调整,按钮会保持在左下角。

2. 建立连接

在InterfaceBuilder中,除了创建和配置视图,还可以将XIB文件中的视图对象连接到应用代码,主要是设置目标 - 动作对和分配指针。
- File’s Owner :在BNRDocument.xib的文档大纲中,“File’sOwner”是一个占位符,代表将XIB文件作为用户界面加载的对象,这里代表BNRDocument的实例。
- 设置按钮的目标 - 动作对
1. 在布局网格中选择“AddTask”按钮,按住Control键,从按钮拖动到文档大纲中的“File’sOwner”。
2. 释放鼠标按钮,会出现方法列表,选择“addTask:”。此时,BNRDocument成为按钮的目标,“addTask:”成为按钮的动作。
3. 由于在BNRDocument.h中“addTask:”方法声明包含了“IBAction”关键字,所以它才会出现在可选方法列表中。“IBAction”实际上是“void”的宏定义,用于告知InterfaceBuilder在连接目标 - 动作对时包含该方法。
4. 为了运行和测试这个连接,需要在BNRDocument.m中实现“addTask:”方法。

#import "BNRDocument.h"
@implementation BNRDocument
#pragma mark - NSDocument Overrides
...
# pragma mark - Actions
- (void)addTask:(id)sender
{
    NSLog(@"Add Task button clicked!");
}
@end
3. 连接表格视图

在BNRDocument.h中声明了“taskTable”指针,需要将BNRDocument.xib中的NSTableView对象分配给该指针。
- 操作步骤
1. 重新打开BNRDocument.xib,按住Control键从“File’sOwner”拖动到布局网格中的表格视图,释放鼠标后从连接列表中选择“taskTable”。
2. “Outlet”是“对象指针”的另一种说法,“IBOutlet”在编译前会被移除。
3. 要将BNRDocument实例分配给表格视图的“dataSource”指针,在布局网格中按住Control - Shift键点击表格视图选择NSTableView,然后按住Control键从表格视图拖动到“File’sOwner”,释放鼠标后选择“dataSource”。

4. 实现NSTableViewDataSource

为了让数据源 - 表格视图关系正常工作,需要在BNRDocument.h中声明BNRDocument遵循NSTableViewDataSource协议,并在BNRDocument.m中实现两个必需的方法。

#pragma mark Data Source Methods
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tv
{
    return [self.tasks count];
}
- (id)tableView:(NSTableView *)tableView
 objectValueForTableColumn:(NSTableColumn *)tableColumn
            row:(NSInteger)row
{
    return [self.tasks objectAtIndex:row];
}
- (void)tableView:(NSTableView *)tableView
   setObjectValue:(id)object
   forTableColumn:(NSTableColumn *)tableColumn
              row:(NSInteger)row
{
    [self.tasks replaceObjectAtIndex:row withObject:object];
    [self updateChangeCount:NSChangeDone];
}

同时,更新“addTask:”方法以实际添加任务。

#import "BNRDocument.h"
@implementation BNRDocument
...
#pragma mark - Actions
- (IBAction)addTask:(id)sender
{
    NSLog(@"Add Task button clicked!");
    if (!self.tasks) {
        self.tasks = [NSMutableArray array];
    }
    [self.tasks addObject:@"New Item"];
    [self.taskTable reloadData];
    [self updateChangeCount:NSChangeDone];
}
5. 保存和加载数据

为了让应用具备保存和重新打开任务列表的功能,需要重写BNRDocument从NSDocument继承的两个方法。

- (NSData *)dataOfType:(NSString *)typeName
                 error:(NSError **)outError
{
    if (!self.tasks) {
        self.tasks = [NSMutableArray array];
    }
    NSData *data = [NSPropertyListSerialization
                         dataWithPropertyList:self.tasks
                                       format:NSPropertyListXMLFormat_v1_0
                                      options:0
                                        error:outError];
    return data;
}
- (BOOL)readFromData:(NSData *)data
              ofType:(NSString *)typeName
               error:(NSError **)outError
{
    self.tasks = [NSPropertyListSerialization
                       propertyListWithData:data
                                    options:NSPropertyListMutableContainers
                                     format:NULL
                                      error:outError];
    return (self.tasks != nil);
}
6. 何时使用InterfaceBuilder

在简单情况下,使用InterfaceBuilder创建用户界面或通过编程方式设置视图都可行。但一般来说,用户界面越复杂,使用InterfaceBuilder越合适。

7. 编写初始化方法

在NSObject类中,“init”方法用于初始化对象的实例变量。下面以创建“Appliances”项目为例,介绍如何编写初始化方法。
- 创建类 :创建两个类“BNRAppliance”和“BNROwnedAppliance”(BNRAppliance的子类)。在BNRAppliance.h中声明“productName”和“voltage”属性。

#import <Foundation/Foundation.h>
@interface BNRAppliance : NSObject 
@property (nonatomic, copy) NSString *productName;
@property (nonatomic) int voltage;
@end
  • 基本的init方法 :为了让每个BNRAppliance实例默认电压为120,在BNRAppliance.m中重写“init”方法。
- (instancetype)init
{
    self = [super init];
    if (self) {
        _voltage = 120;
    }
    return self;
}
  • instancetype :初始化方法应返回“instancetype”,它能让编译器期望返回所属类的实例,确保初始化方法可以安全继承。与返回“id”相比,“instancetype”能让编译器检查返回类型。
  • 使用和检查超类初始化器 :在“init”方法中,首先调用超类的“init”方法并将返回值赋给“self”,然后检查返回值是否为非空。这是因为有些类的“init”方法可能会有异常情况,如重新分配对象或返回nil。
  • 带参数的init方法 :当对象初始化需要额外信息时,需要创建新的初始化方法。对于BNRAppliance,创建“initWithProductName:”方法。
#import <Foundation/Foundation.h>
@interface BNRAppliance : NSObject 
@property (nonatomic, copy) NSString *productName;
@property (nonatomic) int voltage;
- (instancetype)initWithProductName:(NSString *)pn;
@end

- (instancetype)initWithProductName:(NSString *)pn
{
    self = [super init];
    if (self) {
        _productName = [pn copy];
        _voltage = 120;
    }
    return self;
}

为了防止其他程序员使用默认的“init”方法创建无效实例,在BNRAppliance.m中重写“init”方法调用“initWithProductName:”并传递默认名称。

- (instancetype)init
{
    return [self initWithProductName:@"Unknown"];
}
  • 使用访问器 :在初始化方法中,除了直接赋值,也可以使用访问器方法。
- (instancetype)initWithProductName:(NSString *)pn
{
    self = [super init];
    if (self) {
        [self setProductName:pn];
        [self setVoltage:120];
    }
    return self;
}
总结

通过以上步骤,我们完成了TahDoodle应用的构建,包括视图的布局、连接、数据源的实现以及数据的保存和加载。同时,学习了如何编写初始化方法,确保对象在创建时能正确初始化。在实际开发中,根据用户界面的复杂程度选择合适的界面创建方式,并合理使用初始化方法来保证对象的有效性。

流程图
graph TD;
    A[开始构建TahDoodle应用] --> B[设置滚动视图约束];
    B --> C[设置按钮约束];
    C --> D[建立连接(目标 - 动作对、指针分配)];
    D --> E[连接表格视图];
    E --> F[实现NSTableViewDataSource];
    F --> G[保存和加载数据];
    H[创建Appliances项目] --> I[创建类(BNRAppliance、BNROwnedAppliance)];
    I --> J[编写基本init方法];
    J --> K[使用instancetype];
    K --> L[使用和检查超类初始化器];
    L --> M[编写带参数的init方法];
    M --> N[使用访问器];
表格
操作内容 相关文件 关键代码
设置按钮目标 - 动作对 BNRDocument.h、BNRDocument.m - (IBAction)addTask:(id)sender;
连接表格视图 BNRDocument.h、BNRDocument.xib @property (nonatomic) IBOutlet NSTableView *taskTable;
实现NSTableViewDataSource BNRDocument.h、BNRDocument.m - (NSInteger)numberOfRowsInTableView:(NSTableView *)tv;
保存和加载数据 BNRDocument.m - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError;
基本init方法 BNRAppliance.m - (instancetype)init;
带参数的init方法 BNRAppliance.h、BNRAppliance.m - (instancetype)initWithProductName:(NSString *)pn;

构建第一个Cocoa应用与初始化方法详解

8. 测试初始化方法

为了测试 BNRAppliance 类的两个初始化方法,需要实现 description 方法,并在 main.m 中进行测试。

// BNRAppliance.m
- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@: %d volts>", 
                                                     self.productName, self.voltage];
}

// main.m
#import <Foundation/Foundation.h>
#import "BNRAppliance.h"
int main (int argc, const char * argv[])
{
    @autoreleasepool {
        BNRAppliance *a = [[BNRAppliance alloc] init];
        NSLog(@"a is %@", a);
        [a setProductName:@"Washing Machine"];
        [a setVoltage:240];
        NSLog(@"a is %@", a);
    }
    return 0;
}
9. 挑战与拓展

可以为应用添加一个“DeleteSelectedItem”按钮,用于删除当前选中的任务。具体实现步骤如下:
1. 在界面中添加“DeleteSelectedItem”按钮。
2. 为按钮设置目标 - 动作对,目标为 BNRDocument 实例,动作可以命名为 deleteSelectedItem:
3. 在 BNRDocument.m 中实现 deleteSelectedItem: 方法,该方法需要获取当前选中的任务并从 tasks 数组中移除,然后刷新表格视图并标记文档为有未保存更改。

// BNRDocument.h
- (IBAction)deleteSelectedItem:(id)sender;

// BNRDocument.m
- (IBAction)deleteSelectedItem:(id)sender
{
    NSInteger selectedRow = [self.taskTable selectedRow];
    if (selectedRow != -1) {
        [self.tasks removeObjectAtIndex:selectedRow];
        [self.taskTable reloadData];
        [self updateChangeCount:NSChangeDone];
    }
}
10. 总结与回顾

在构建Cocoa应用和编写初始化方法的过程中,我们学习了多个重要的知识点:
- Cocoa应用构建 :通过 InterfaceBuilder 和代码结合的方式,完成了 TahDoodle 应用的界面布局、视图连接、数据源实现以及数据的保存和加载。
- 初始化方法编写 :了解了基本的 init 方法、 instancetype 的使用、超类初始化器的检查、带参数的初始化方法以及访问器在初始化中的应用。

表格
知识点 关键内容
Cocoa应用构建 滚动视图约束、按钮约束、目标 - 动作对设置、表格视图连接、数据源实现、数据保存和加载
初始化方法编写 基本 init 方法、 instancetype 、超类初始化器检查、带参数初始化方法、访问器使用
流程图
graph TD;
    A[测试初始化方法] --> B[实现description方法];
    B --> C[在main.m中测试];
    D[挑战拓展] --> E[添加Delete按钮];
    E --> F[设置目标 - 动作对];
    F --> G[实现deleteSelectedItem:方法];
    H[总结回顾] --> I[Cocoa应用构建知识点];
    H --> J[初始化方法编写知识点];
总结

通过构建 TahDoodle 应用和编写 Appliances 项目中的初始化方法,我们掌握了Cocoa应用开发的基本流程和Objective - C中初始化方法的编写技巧。在实际开发中,要根据具体需求合理运用这些知识,确保应用的稳定性和可维护性。同时,不断挑战和拓展应用功能,提升自己的开发能力。

"Mstar Bin Tool"是一款专门针对Mstar系列芯片开发的固件处理软件,主要用于智能电视及相关电子设备的系统维护深度定制。该工具包特别标注了"LETV USB SCRIPT"模块,表明其对乐视品牌设备具有兼容性,能够通过USB通信协议执行固件读写操作。作为一款专业的固件编辑器,它允许技术人员对Mstar芯片的底层二进制文件进行解析、修改重构,从而实现系统功能的调整、性能优化或故障修复。 工具包中的核心组件包括固件编译环境、设备通信脚本、操作界面及技术文档等。其中"letv_usb_script"是一套针对乐视设备的自动化操作程序,可指导用户完成固件烧录全过程。而"mstar_bin"模块则专门处理芯片的二进制数据文件,支持固件版本的升级、降级或个性化定制。工具采用7-Zip压缩格式封装,用户需先使用解压软件提取文件内容。 操作前需确认目标设备采用Mstar芯片架构并具备完好的USB接口。建议预先备份设备原始固件作为恢复保障。通过编辑器修改固件参数时,可调整系统配置、增删功能模块或修复已知缺陷。执行刷机操作时需严格遵循脚本指示的步骤顺序,保持设备供电稳定,避免中断导致硬件损坏。该工具适用于具备嵌入式系统知识的开发人员或高级用户,在进行设备定制化开发、系统调试或维护修复时使用。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值