(目标:对象)不适用于从 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 中的多个视图控制器

CATiledLayer 不适用于我的 iOS5 项目

在 UINavigationController 中,按钮不适用于 pushViewController

来自 equatable 协议的 func == 不适用于自定义对象,swift