使用访问器方法设置 iVar?

2023-12-31

最初,我正在研究“pickerData”的设置方式,并想知道为什么不能直接分配它(如 METHOD_002 中),但后来我说我应该真正使用我定义的访问器方法而不是直接设置实例变量。我是否正确理解 METHOD_001 是执行此操作的更好方法?

@property(nonatomic, retain) IBOutlet NSArray *pickerData;

方法_001

-(void)viewDidLoad {
    NSLog(@"VIEW: Single ... Loaded");
    NSArray *dataArray = [[NSArray alloc] initWithObjects:@"A", @"B", @"C",nil];
    [self setPickerData:dataArray];
    [dataArray release];
    [super viewDidLoad];
}

-(void)dealloc {
    [pickerData release];
    [super dealloc];
}

或方法_002

-(void)viewDidLoad {
    NSLog(@"VIEW: Single ... Loaded");
    if(pickerData != nil) [pickerData release];
    pickerData = [[[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil] retain];
    [super viewDidLoad];
}

-(void)dealloc {
    [pickerData release];
    [super dealloc];
}

编辑_001:

首先,我添加了“nil”值来终止 NSArray,来自 C 我总是忘记这一点,我的错。你也是对的,我没有考虑到 METHOD_002 中 pickerData 可能已经被设置的事实,因此泄漏了旧对象。一旦您开始注意到这些问题并修复代码,它就会开始看起来 METHOD_001 是最好的主意。或者像弗拉基米尔和埃詹姆斯指出的那样直接使用该财产。

self.pickerData = [NSArray arrayWithObjects: @"A", @"B", @"C", nil];

编辑_002:

感谢您的所有指针和评论,现在我将坚持使用 METHOD_001,我可以轻松地使用 NSArrayWithObjects: 但我试图通过尽快释放自己的东西来保持较低的内存使用率(这并不重要)在这里,但对于未来的项目)我也确实喜欢 self.pickerData 的感觉,但我仍然不确定我对点表示法的感觉,并且目前一直在尽可能坚持使用旧样式的对象和消息。再次非常感谢您的帮助。

gary


您应该始终使用属性的访问器(在 Objective-C 2.0 中意味着使用self.property符号。)

为什么?因为它提供了自动访问控制和对象生命周期管理。生成的访问器可以提供很多保护,例如读/写、复制、保留等,否则需要大量手动代码。如果您编写自己的访问器,则可以添加所需的所有验证和副作用。

(早在 Objective-C 2.0 编写访问器之前就被认为是一门高雅艺术。如果你充分利用潜力,它仍然可以是一门高雅艺术。)

唯一应该直接访问属性的时候是编写访问器时。例如,采用以下常见模式:

@property(nonatomic, retain)  NSMutableArray *myObjects;
@synthesize myObjects;

-(NSMutableArray *) myObjects{
    if (myObect!=nil) {
        return myObect;
    }
    NSMutableArray *anArray=[[NSMutableArray alloc] initWithCapacity:1];
    self.myObject=anArray;
    [anArray release]
    return myObject;
}
  1. 这个访问器确保 myObjects 永远不会为零,这消除了代码其余部分中的大量样板 nil 测试。
  2. 你显然不能打电话self.myObjects(这实际上是 [self myObjects] )在访问器内部,而不创建无限递归,因此您必须在此处访问原始变量,但是......
  3. ...您可以调用(自动生成的)self.myObjects=(这实际上是 [self setMyObjects:anArray] )因为它是一个完全不同的方法。如果您查看 setMyObjects: 的内部结构,您会发现它也访问原始变量。
  4. 如果您使用生成的访问器,self.myObjects=每次您调用它时,都会为您处理保留、复制、清空等。唯一需要调用release 的时间是在dealloc 中。仅此一项就可以消除人们在 Objective-C 中所犯的错误的一半。

相反,在访问器方法之外,直接访问类自己的方法内的属性绝对不会获得任何好处。它所做的只是节省一些按键操作,同时让您面临难以发现错误的风险。

正如前面的答案所示,您在尝试直接管理属性时犯了几个内存错误。如果您每次都使用访问器,您就不会制作它们。例如:

pickerData = [[[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil] retain];

...每次都必须正确管理,而...

self.pickerData = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil];

...自动正确。

请记住,任何 Objective-C 类的最终设计目标都是应该完全模块化和可重用。这意味着它应该管理自己的所有内存、自己的数据验证和自己的副作用。访问器对于该管理绝对至关重要。通过将逻辑包装在变量的每次访问周围,您可以确保 (1) 它是您期望的类型、范围等,并且 (2) 当您需要它时它始终存在 (3) 您可以控制所有方面写入或读取变量的影响以及 (4) 它不会泄漏。

我对访问器的优点赞不绝口。事实上,我可能会写一首小歌。 ;-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用访问器方法设置 iVar? 的相关文章

  • EKEvent 事件标识符返回 null

    当我尝试获取 EKEvent 的标识符时 我得到的只是一个 nil 值 由于在 iOS5 中 EKEvent 是 EKCalendarItem 的子类 因此我想我也许能够获取 EKCalendarItem 的 UUID 但它也会返回 nil
  • ld:仅在 64 位 iPhone 上找不到架构 armv7s 错误的符号

    我收到 ld symbol s not found for Architecture armv7s 错误 但仅当我在 iPhone 64 位上运行它时才收到 它适用于 iOS6 和 iOS7 的 32 位手机 也适用于 64 位 iOS7
  • 来自 NSString 的 iOS SecKeyRef

    我需要使用公钥将用户密码加密为 Base64 字符串 公钥是一个 NSString 像这样的东西 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgWO7p1AvCaHUeaM6rSczBBAqt mKObHx
  • iOS 6 仅支持一个视图的不同方向

    我只想将应用程序中的一个视图旋转到左横向或右横向 我的所有其他视图均处于纵向模式 并且我已将我的应用程序设置为仅支持纵向模式 随着 iOS 6 中方向的改变 我不知道如何做到这一点 我已经尝试过下面发布的内容 谁能告诉我我做错了什么 谢谢
  • iOS:管理本地化图像

    我有 2 组 iPhone 应用程序的本地化图像 我应该如何放置图像 我如何加载到应用程序中 文件夹结构如下 For English version MyApp en lproj Localizable strings InfoPList
  • UICollectionView 和补充视图(标题)

    尝试将补充视图添加到我的UICollectionView作为标题 我在让它工作时遇到问题 我用的是自定义的UICollectionViewFlowLayout返回一个contentSize总是比框架大至少 1 像素 我使用的是UIFresh
  • 重新排序单元格后重新加载自定义 UITableViewCell

    I have UITableView它使用自定义UITableViewCells 单元格可以具有三种类型的背景图像之一 在每个单元格的 backgroundView image属性 顶部 中间或底部 顶部和底部图像用于第一个和最后一个单元格
  • 多对多关系中的 KVO 对象属性

    我有一个核心数据对多关系 由父 gt 子组成 我想设置一个键值观察机制 以便当任何子对象上的属性 例如 firstName lastName 发生更改时 它会触发通知 使用标准 KVO 语法时 self parentObject addOb
  • iOS 应用程序和.NET 应用程序之间的通信?

    我有 2 个应用程序 一个是 iOS 应用程序 一个是 NET 应用程序 我希望我的 iOS 应用程序发送一条消息 调用 NET 应用程序的方法 将一些字符串发送到 NET 应用程序以保存到数据库 那么 我的 iOS 应用程序如何与 NET
  • object_setClass()而不是分配isa指针的性能

    我注意到在 XCode 4 6 的最新更新中 我收到了关于以下几行的警告JSONKit m 具体来说 设置对象类的行 dictionary gt isa JKDictionaryClass 这些被标记为已弃用 并注明首选方法是使用objec
  • Swift 和 Objective-C 框架公开其内部结构

    我正在尝试将 Swift 添加到具有公共 私有和项目文件的现有 Objective C 框架中 为了让 Swift 能够访问项目文件 我添加了一个定义新模块的模块映射 例如MyFramework Internal 通过包含所有项目标题 如下
  • 外围 BLE 设备的唯一标识符

    所以我有外围设备BLE设备 我需要一些标识符以便稍后与另一部 iPhone 共享 我连接的示例iPhone A 为外围设备 iPhone A 将外围设备的标识符保存到数据库中 稍后我可以轻松获取iPhone B 并连接到通过该标识符找到的外
  • iOS8中如何在UIAlertController中添加UITableview?

    Till iOS7 in Custom view we can put tableview in alert as per below picture But in iOS8 UITableview is not working I can
  • 由于无法确认开发者身份而无法打开

    我在 Mac OSX 中开发了一个应用程序和守护进程 并且我已经在 xcode 中与开发者 ID 签署了应用程序和守护进程源代码 在守护进程中 我已经对每个框架进行了签名并打包 并且我使用软件包安装程序对所有框架进行了 pkg 现在我的应用
  • 取消交互式 UINavigationController 弹出手势不会调用 UINavigationControllerDelegate 方法

    如果拖动 a 的边缘UIViewController开始交互式流行过渡UINavigationController the UIViewController在电流下方有viewWillAppear 调用 然后是UINavigationCon
  • Apple 推送通知徽章编号

    我开发了服务器端应用程序 以在收到新通知后将徽章编号维护为递增或递减 并在看到通知后删除它工作正常 但是显示徽章时存在一些问题 实际情况是 在设备上收到新通知后 我单击取消按钮 然后徽章编号正确显示 但之后我将打开应用程序并关闭应用程序徽章
  • StoryBoard 2 导航控制器指向相同的视图

    有谁知道为什么这不起作用 这样 只有一个选项卡栏加载视图 另一个选项卡栏则显示黑屏 我在没有导航控制器的情况下尝试过 选项卡栏是正确的 而另一个在运行模式下不显示选项卡栏项目 如果有人感兴趣的话我对这个问题的回答 添加两个视图来启动我们感兴
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 为什么 iOS 5.0 不喜欢纯窗口应用程序?为什么它要求使用视图控制器?

    我有一个使用 Xcode 4 0 的 基于窗口的应用程序 模板创建的 iOS 应用程序 当时运行良好 并且使用的是 iOS 4 3 SDK 这是一个简单地将按钮 标签等直接放置到窗口上的应用程序 没有视图控制器 什么都没有 但现在我已经升级
  • 桌面上的 AVAudioSession?

    在 mac 桌面上 我试图录制系统声音 以及可选的麦克风声音 但一开始我只是录制系统声音 我正在遵循本指南 https www appcoda com ios avfoundation framework tutorial https ww

随机推荐

  • RTK 查询:一次性转换所有查询响应

    通过 RTK 查询 端点的响应可以转换为transformResponse https redux js org tutorials essentials part 8 rtk query advanced transforming res
  • “使用 POSTMAN 发布图像数据”

    我正在尝试将数据发布到我的 API 我有一个模型image字段其中 image models ImageField 我的本地盒子上有一张图像 我正在尝试发送该图像 我发送正确吗 id 3 uid 273a0d69 uuid 90 image
  • C# Azure 存储 Blob 上传 TransactionScope

    是否有某个类允许在 azure blockblob 操作上使用 transactionscope 进行回滚 我想让这个工作 CloudBlockBlob blockBlob private void UploadPicture Stream
  • 访问自定义授权 MVC4 Web Api 中的 post 或 get 参数

    是否可以通过 HttpActionContext 对象访问 post 或获取参数 我有一组传感器 用于将数据记录到提供 REST API 的 Web 服务器 我想引入某种身份验证 授权 让传感器在数据中包含其硬件 ID 然后在数据库中查找该
  • 当我在cmd上运行meteor应用程序时它崩溃了

    我是流星新手 请帮忙 我创建了我的第一个应用程序 但是当我尝试运行它以便可以在浏览器上查看它时 我收到以下错误消息 C projects myapp gt meteor C projects myapp gt Started proxy g
  • 使用 R 合并数据帧的互补行

    我有这样一个数据框 0 weekday day month year hour basal bolus carb period h 1 Tuesday 01 03 2016 0 0 0 25 NA NA 0 2 Tuesday 01 03
  • 调用方法的义务

    在VB NET 中 当您创建用户控件类时 您有义务在构造函数中调用子InitializeComponent 如果不这样做 您将收到如下警告消息 Public Sub New 中 设计者生成的类型 MyUserControl 应该调用 初始化
  • 方法链和流畅接口之间的区别

    我想知道方法链接和流畅接口之间的确切区别 据我了解 方法链只是运行先前方法返回对象的方法 同时避免临时变量 这方面的一个例子可能是 Integer parseInt str intValue 相对于Fluent Interface 对象的每
  • 使用clearTimeout取消超时事件

    我有以下代码 但明确的超时不起作用 我不明白为什么 有人有任何想法吗 使用Prototype框架 function foo navigation observe mouseover function event clearTimeout b
  • MVVM - 从 ViewModel 后面的代码中调用 UI 逻辑

    我正在使用 MVVM 模式开发一些 Net XAML 应用程序 根据 MVVM 我将应用程序逻辑保留在 VM 中 并在代码隐藏中执行与 UI 相关的操作 但我需要在Code Behind中执行一些UI相关的代码来响应VM中的一些逻辑 例子
  • 从文本文件读取并存储在字符串中[重复]

    这个问题在这里已经有答案了 我们如何从文本文件中读取数据并将其存储在字符串变量中 是否可以在方法中传递文件名 然后返回文件中的文本字符串 我必须导入哪些类型的实用程序 一份陈述清单会很棒 这些是必要的进口 import java io Bu
  • RVM ruby​​ on Rails 问题 OpenSSL

    当我创建 Rails 应用程序时 我遇到了一些错误 但我不知道它们的含义或如何修复它们 我认为这可能是获得帮助的最佳方法 而不是解释我将输出正在发生的事情 j3 j3 code rails projects rails new first
  • 在单元测试期间模拟 Angular2 中的自定义服务

    我正在尝试为我的服务中使用的组件编写单元测试 组件和服务工作正常 成分 import Component from angular core import PonyService from services import Pony from
  • ExcludeFoldersFromDeployment 在发布配置文件中不起作用

    我尝试使用 ExcludeFoldersFromDeployment 排除发布配置文件中的文件夹 但在发布到 azure app 服务时它不是 wxinclude 文件夹位置 a b c 文件夹名称 如果有人可以帮忙请告诉我 如果您在此环境
  • 有条件 if 对于许多值,更好的方法

    有没有更好的方法来处理检查多个值 当我有超过 3 个选择时 事情就开始变得非常忙碌 if myval something myval other myval third PHP有一个函数叫做in array 像这样使用 in array m
  • C 语言蓝牙编程 - 安全连接和数据传输

    我正在尝试用 C 编写程序通过蓝牙发送 接收数据 我参考了 Albert Huang 写的一本书 里面有示例程序和很好的信息来源 关联 https people csail mit edu albert bluez intro index
  • mysql检查两列之间的预订重叠时间

    我有一个表预订 其中有两列 job time beg 和 job time end 工作从 8 00 开始一直持续到 16 00 现在我需要确定可用时间是否与给定时间重叠 以便我知道我不想在给定时间内预订时间 我在用 select coun
  • 结构体中的枚举; c 新手

    我想知道使用的语法enum in a struct in C 我见过各种例子struct union enum组合用于创建复杂类型 例如 struct MyStruct enum TYPE 1 TYPE 2 TYPE 3 type unio
  • 从int到向量的隐式转换?

    vector
  • 使用访问器方法设置 iVar?

    最初 我正在研究 pickerData 的设置方式 并想知道为什么不能直接分配它 如 METHOD 002 中 但后来我说我应该真正使用我定义的访问器方法而不是直接设置实例变量 我是否正确理解 METHOD 001 是执行此操作的更好方法