(目标:对象)不适用于从 viewController 外部设置 UIButton
Posted
技术标签:
【中文标题】(目标:对象)不适用于从 viewController 外部设置 UIButton【英文标题】:(Target: Object) not working for setting UIButton from outside viewController 【发布时间】:2012-05-06 22:45:33 【问题描述】:我可以创建 UIButton。 但是回调:目标:对象在当前对象中不起作用。 ?? 我只能做“self.viewController”对象,不能做当前对象的“self”。
谢谢
#import <Foundation/Foundation.h>
#import "ViewController.h"
@class ViewController;
@interface CGuiSetup : NSObject
@public
ViewController *viewController;
- (void) Setup;
- (void) ButtonRespond:(UIButton*) btn;
@end
#import "CGuiSetup.h"
@implementation CGuiSetup
- (void) ButtonRespond:(UIButton*) btn
NSLog(@"ButtonRespond");
- (void) Setup
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(10,10,100,100)];
// But I want to call the following in the CGuiSetup object (self) instead... but it crashes out if I leave it as just "self"
[btn addTarget:self.viewController action:@selector(ButtonRespond:)
forControlEvents:UIControlEventTouchUpInside]; //works: for "self.viewController" if I put ButtonRespond in the ViewController
[btn addTarget:self action:@selector(ButtonRespond:)
forControlEvents:UIControlEventTouchUpInside]; //fails: for "self"
[self.viewController.view addSubview:btn];
@end
#import <UIKit/UIKit.h>
#import "CGuiSetup.h"
@class CGuiSetup;
@interface ViewController : UIViewController
CGuiSetup *guiSetup; //<---- had to take this out of the "viewDidLoad" method
@end
- (void)viewDidLoad
[super viewDidLoad];
guiSetup = [CGuiSetup alloc];
guiSetup->viewController = self;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(10,10,100,100)];
[btn addTarget:guiSetup action:@selector(ButtonRespond:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
【问题讨论】:
头文件也能发一下吗? 【参考方案1】:如果您使用 ARC,是否有任何对象具有对 CGuiSetup 的保留引用?我听起来像 CGuiSetup 被实例化,创建(或者可能从另一个对象接收)viewController,将按钮添加到它,然后将视图控制器提供给另一个对象(可能通过将它推到 navController 上或将其设置为的根控制器应用程序)?不管是什么情况,CGuiSetup 都会被释放,并且按钮正试图向已经被销毁的对象发送消息。 CGuiSetup 是如何/在哪里创建的?什么对象保留了对它的引用?这可能就是你的问题所在。
如果您不了解什么是保留/释放和/或您不知道什么是 ARC,则需要阅读 Apple 的内存管理指南:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
【讨论】:
谢谢...我不得不将对象作为实例变量放在 ViewController 类中。 你是说CGuiSetup有一个实例变量的ViewController类吗?如果是这样,您将有一个保留周期(内存泄漏)。这些对象永远不会被释放。这对你来说可能没问题,但你应该意识到这一点。 我添加了代码来显示我移动它的位置......所以从这里有内存泄漏吗?我想把 Gui 的东西从 ViewController 中拉出来,放到另一个类中。 是的,这确实会创建一个保留周期(内存泄漏)。尤其是在 ARC 下,这两个类永远不会被释放。由于 viewController 似乎拥有 CGuiSetup,因此您需要考虑将 __weak 添加到 CGuiSetup 中的 viewController iVar:__weak ViewController *viewController;
这将告诉 ARC 不要保留它。您可能还想重新考虑您的设计。为什么 CGuiSetup 需要有 viewController 的引用? viewController 不应该处理它自己的按钮并响应它们吗?也许,也许不是……只是想一想。【参考方案2】:
这可能是因为您的对象已被销毁,而 _viewController 的保留计数仍大于 0(因此它没有被销毁)。平衡您保留/释放的数量。
【讨论】:
你是什么意思“平衡你保留/释放的数量。” ??谢谢 取出“属性”并将其设为公共变量... self 或 self.viewController 的结果相同。以上是关于(目标:对象)不适用于从 viewController 外部设置 UIButton的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 UIStatusBarStyle 不适用于 UINavigationController 中的单独 ViewController
CALayer 旋转动画不适用于呈现的 ViewController
返回上一个 ViewController 不适用于 Swift 中的多个视图控制器