- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
直到现在,我一直认为self->_ivar
等同于_ivar
。今天我发现这并不完全正确。
例如,请参见以下代码片段:
@interface TestClass : NSObject {
NSString *_testIVar;
}
@end
@implementation TestClass
- (instancetype)init
{
if ((self = [super init])) {
_testIVar = @"Testing Only";
}
return self;
}
- (void)test
{
{
NSInteger self = 42;
NSLog(@"without arrow: %@", _testIVar); /* OK */
NSLog(@"with arrow: %@", self->_testIVar); /* COMPILER ERROR! */
}
}
@end
即使我用一些也命名为 self
的 NSInteger
隐藏了原始的 self
,隐式的 ivar 语法 _testIVar
仍然找到“原始” self ,而 self->_testIVar
显然没有。在后一种情况下,编译器正确地提示
Member reference type 'NSInteger' (aka 'long') is not a pointer
然而,在第一种情况下,它只是有效。
这个例子可能看起来很不自然,但事实并非如此。例如 ExtObjC项目(由 ReactiveCocoa 使用)定义了非常方便的 @weakify(var)
和 @strongify(var)
这有助于防止强烈捕获 self
(和其他对象)在 block 中定义一个非常方便的语法(不需要编写奇怪和繁琐的代码来编写 __weak typeof(self) weakSelf = self; [...] ^{ __strong typeof(self) strongSelf = weakSelf; [...]
了)。例如:
- (void)someMethod
{
@weakify(self);
dispatch_async(self.someQueue, ^{
@strongify(self);
NSLog(@"self @ %p", self);
}
}
如果没有 @weakify
和 @strongify
,该 block 将捕获对 self
的强引用。使用 @weakify
和 @strongify
则不会。所以 self
的释放不会被推迟,直到 block 已经运行。不过,主要优点是您不需要记住使用 weakSelf
或 strongSelf
而不是 self
因为“原始” self
是隐藏的。
这非常方便,ExtObjC 通过使用宏生成类似于以下内容的内容来实现 @weakify
/@strongify
:
- (void)someMethod
{
__weak typeof(self) _weakSelf = self;
dispatch_async(self.someQueue, ^{
__strong typeof(self) self = _weakSelf;
NSLog(@"self @ %p", self);
}
}
很公平,这更好,因为我们可以继续使用 self
而无需实际捕获对 self
的强引用。然而,一旦我们使用 implicit-ivars-of-self-syntax,对“原始”self
的强引用仍将被捕获!
- (void)someMethod
{
@weakify(self);
dispatch_async(self.someQueue, ^{
@strongify(self); /* compiler warning: Unused variable self here!!! */
NSLog(@"self->_testIVar: %@", _testIVar);
}
}
在 block 中使用 ivars 时,我们肯定会捕获 self
。例如,请参见此屏幕截图: .
屏幕截图的另一个有趣之处在于警告消息是
Unused variable 'self'
在下面一行
Capturing 'self' strongly in this block is likely to lead to a retain cycle
这就是为什么我认为有两个版本的 self
:-)
这里的实际问题是:_testIVar
到底是什么意思?它如何找到“原始”self
指针?
澄清一下(另请参阅我的屏幕截图):正如@MartinR 指出的(我也是这么认为的),有一些特殊版本的 self
无法更改,仅用于隐式 self 变量访问。这在某处记录了吗?基本上在哪里定义了隐式 self
指的是什么?它的行为方式似乎与例如 Java 的行为方式相同(使用 this
),但不同之处在于 this
是您无法覆盖的保留关键字。
问题也不是如何“修复”它,只需编写 self->_testIVar
就是我想要的 @weakify
/@strongify
示例。更多的是,我认为通过使用 @weakify
/@strongify
你不能再犯隐式强捕获 self
的错误,但这似乎不是确实如此。
最佳答案
所有 Objective-C 方法都使用两个隐藏参数调用(来自 "Objective-C Runtime Programming Guide" ):
并且方法可以将接收对象引用为self
(并将其自己的选择器引用为_cmd
)。
现在 _ivar
等同于 self->_ivar
其中 self
是隐式优先函数参数。只要您不在内部范围内定义新变量 self
,_ivar == self->_ivar
就成立。
如果您在内部作用域中定义了一个新变量self
,那么您就有了
self
,和_ivar
仍然指的是“内隐 self ”!这解释了你的 block 中的编译器警告,它们似乎相互矛盾:
self
,下面的代码也证明了这一点:
@interface MyClass : NSObject
{
NSString *_ivar;
}
@end
@implementation MyClass
- (void)test
{
_ivar = @"foo"; // Set instance variable of receiver
{
MyClass *self = [MyClass new]; // Redefine self in inner scope
self->_ivar = @"bar"; // Set instance variable of redefined self
NSLog(@"%@ - %@", self->_ivar, _ivar);
// Output: bar - foo
}
}
@end
关于Objective-C self->_ivar 访问显式与隐式 self->,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19661808/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!