1

我有一个工作区,里面有两个项目。第一个项目本质上是一个测试和开发项目,在我担心将所有东西真正捆绑在一起之前,我已经开始工作了。第二个项目是将我所有单独开发的视图控制器放在一个故事板中。

在其中一个视图控制器上,我有一堆滑动手势和相当多的 UIView 动画调用,它们的格式很好地为可读性而设计,因此占用了大量空间。我选择将它们作为一个类别移出。

问题是编译器没有在主头文件中看到实例变量声明。

让我大吃一惊的是,我在第一个项目中就这样做了,而且一切正常。所以我仔细比较了我的第二个项目和第一个项目的内容,我没有发现任何差异。

以下是一些文件片段,可帮助演示我如何/在何处定义事物,然后是类别文件中尝试访问它们的代码片段:

GSBViewController.h

@interface GSBViewController : UIViewController

@property (strong, nonatomic) IBOutlet UISegmentedControl *roundPicker;
@property (strong, nonatomic) IBOutlet UIView *roundsSectionView;

GSBViewController.m

#import "GSBViewController+Swipe.h"

@interface GSBGameBuilderViewController ()
{
    UIBarButtonItem *rightGatherBarButton;

    NSInteger previousRound;
}
@end

@implementation GSBViewController
@synthesize roundPicker;
@synthesize roundsSectionView;

GSBViewController+Swipe.h

#import "GSBViewController.h"

@interface GSBViewController (Swipe)

- (void)establishSwipeGestures;

@end

GSBViewController+Swipe.m

#import "GSBViewController+Swipe.h"

@implementation GSBViewController (Swipe)

- (void)establishSwipeGestures
{
    UISwipeGestureRecognizer *swipeLeft = 
       [[UISwipeGestureRecognizer alloc] 
           initWithTarget:self 
                   action:@selector(roundsSectionLeft:)];

    [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
    [swipeLeft setNumberOfTouchesRequired:1];
    [roundsSectionView addGestureRecognizer:swipeLeft];
// bunch-o-code snipped -- for the time being it's actually all commented out
// as a test and because the LLVM compiler was giving up after too many errors
// and I wanted to see if there was more it would like to tell me about this first --
// and very representative -- problem.
}
@end

编译器的抱怨是“使用未声明的标识符'roundsSectionView'”

如果我在向其中添加手势识别器的那行代码中单击使用 roundsSectionView,则弹出窗口正确地描述了它,如 GSBViewController.h 中所声明的那样

所以我很难过。

我可以在 Xcode 中做些什么(发帖时为 4.3.2 :-) 让我看看包含的文件是什么?或者是否需要一些非基于文件的东西来将一个类别与它正在扩充的类联系起来?我不记得以前有什么必要的。事实上,我为这个类别生成文件的方式是通过 Xcode 的 File -> New File... Objective-C Category 模板。然后我只是复制了旧的 ...+Swipe.h 和 ...+Swipe.m 文件的内容,并将它们粘贴到新项目中各自的文件中。

4

2 回答 2

2

合成的 ivar 是私有的。编译器不允许您在任何地方访问它,除了在@implementation它创建的块中。类别和子类都不能直接访问 ivar;他们必须使用以下属性:[self roundsSectionView]

早期的 Clangs 没有将合成的 ivars 设为私有的可能性很小。要么就是这样,要么你在早期的项目中并没有真正做同样的事情。

于 2012-05-29T06:53:41.757 回答
1

@Jacques Cousteau 说的是正确的。

由于您刚刚定义了一个属性并且没有支持 ivar,因此该类别将无法访问它。如果您使用self.roundsSectionView它将使用为该属性生成的 getter 方法,因此它将起作用。

或者你可以在你的界面中定义一个支持变量

@interface GSBViewController : UIViewController
{
    UIBarButtonItem *roundsSectionView;
}

在这种情况下,类别将能够访问该变量。但不是任何其他类。

于 2012-05-29T07:05:44.060 回答