简体   繁体   中英

Why I have to add IBOutlet identifier to my delegate when inside apple sdk there isn't any IBOutlets?

I've created the following custom view:

@interface TNGalleryView : UIView

@property (assign, nonatomic) id <TNGalleryViewDelegate> delegate;
@property (assign, nonatomic) id <TNGalleryViewDataSource> dataSource;

@end

I can assign delegate of it in code, but when I want to assign delegate in IB, I can't. I have to change my code to:

@interface TNGalleryView : UIView

@property (assign, nonatomic) IBOutlet id <TNGalleryViewDelegate> delegate;
@property (assign, nonatomic) IBOutlet id <TNGalleryViewDataSource> dataSource;

@end

and then I can assign delegate and dataSource in IB.

Why if i would like to assign delegate and dataSource in IB I have to add IBOutlet identifier, but inside apple sdk there isn't any IBOutlets? For example this part of UICollectionView declaration:

NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView

- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout; // the designated initializer

@property (nonatomic, retain) UICollectionViewLayout *collectionViewLayout;
@property (nonatomic, assign) id <UICollectionViewDelegate> delegate;
@property (nonatomic, assign) id <UICollectionViewDataSource> dataSource;

There isn't any IBOutlet, nevertheless I can assign dataSource and delegate to it in IB.

The IBOutlet decorator is to let Interface builder know that it can connect to the property. It is just a hint that produces no code.

Only those properties that will connect to Interface elements need IBOutlet. That is the objects that you connect by dragging between the GUI object and the code. It is a hint to Interface builder that a property in the code can be connected to.

Quite a good question!

Open your storyboard/xib with text editor,search "TNGalleryView",you will found xml tag like this:

<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ke7-rk-01e" customClass="TNGalleryView">
    <rect key="frame" x="86" y="309" width="160" height="252"/>
    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>

Note that: TNGalleryView was wrapped in a "view" tag with a property: customClass="TNGalleryView"

Now add a UICollectionView in storyboard/xib, save and reopne storyboard/xib with text editor,search "collectionView",you will found xml tag like this:

<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="ouM-xa-T6a">
   <rect key="frame" x="93" y="72" width="160" height="252"/>
   <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
   <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Cv0-O7-zGY">
   <size key="itemSize" width="50" height="50"/>
   <size key="headerReferenceSize" width="0.0" height="0.0"/>
   <size key="footerReferenceSize" width="0.0" height="0.0"/>
   <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
    </collectionViewFlowLayout>

</collectionView>

Now,you will find the different ,collectionView is wrapped in a "collectionView" tag

I guess that was the reason why you can't assign custom delegate in IB without set the custom delegate to be a IBOutlet.

UPDATE

No enought reputation to comment other poeple's answer.So i say something here: read the question clearly,and have a test in xcode,you will realize what Sergey Demchenko's question is:

First,if TNGalleryViewDelegate is declare in this way:

@property (assign, nonatomic) id <TNGalleryViewDelegate> delegate;

The xcode screen shot: 在此输入图像描述

Now if TNGalleryViewDelegate is declare in this way:

@property (assign, nonatomic) IBOutlet id <TNGalleryViewDelegate> delegate;

The xcode screen shot: 在此输入图像描述

Actually this is a pretty good question. Since Xcode and IB are opaque - meaning no one but Apple has the source, all we can do is guess. My guess is that given the relatively small number of UIView subclasses that take delegates and data sources, Apple has just hardcoded the knowledge into IB.

One reason for this would be that IB doesn't want to parse every one of those UIView subclasses every time you switch to a Storyboard or NIB view.

In any case, all we can do is speculate. Its not so difficult adding the IBOutlet keyword to your own file.

Outlets are not necessarily exposed in the header file. You can do the same in your own classes by defining the outlets inside your .m file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM