0

A UIImageView category has been defined in HDScrollview.h. It is not imported in GoodDetailViewController.m, But when the code cell = [[[NSBundle mainBundle] loadNibNamed: CellIdentifier owner: self options: nil] lastObject]; runs, -(id)initWithCoder:(NSCoder *)aDecoder in HDScrollview.m will get called. What's going on here? Any help will be appreciated.

ps.

HDScrollview.h is imported in GoodDetailViewController.m but not in GoodDetailViewController.h

GoodsListViewController.m

...
#import "GoodDetailViewController.h"
...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == _mutableArrayGoods.count) {
        return [self setLoadMoreCell];
    }

    static NSString *CellIdentifier = @"TableViewCellGoods";
    TableViewCellGoods *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[NSBundle mainBundle] loadNibNamed: CellIdentifier owner: self options: nil] lastObject];
        [cell initGoodsCellDefaultStyle];
    }

    // Configure the cell...
    if ( indexPath.row < _mutableArrayGoods.count ) {
        Good *good = [_mutableArrayGoods objectAtIndex: indexPath.row];
        cell.good = good;
        cell.delegate = self;
    }

    return cell;
}

HDScrollview.h

#import <UIKit/UIKit.h>
#import "HdPageControl.h"
@protocol HDScrollviewDelegate <NSObject>
-(void)TapView:(int)index;
@end

@interface HDScrollview : UIScrollView<UIScrollViewDelegate>

@property (nonatomic,strong) HdPageControl *pagecontrol;
@property (nonatomic,assign) NSInteger currentPageIndex;
@property (assign,nonatomic) id<HDScrollviewDelegate> HDdelegate;

-(id)initWithFrame:(CGRect)frame withImageView:(NSMutableArray *)imageview;

-(id)initLoopScrollWithFrame:(CGRect)frame withImageView:(NSMutableArray *)imageview;
-(void)HDscrollViewDidScroll;
-(void)HDscrollViewDidEndDecelerating;
@end

@interface UIImageView (CopyImageview)<NSCoding>
@end

HDScrollview.m

...

@implementation UIImageView (CopyImageview)
-(void)encodeWithCoder:(NSCoder *)aCoder
{

    [aCoder encodeObject:self.backgroundColor forKey:@"backgroundColor"];
    [aCoder encodeObject:self.image forKey:@"image"];
    [aCoder encodeInt:self.contentMode forKey:@"contentMode"];
    [aCoder encodeInt:self.subviews.count forKey:@"subviewscount"];
    for(int i=0;i<self.subviews.count;i++)
    {
        UIView *view=self.subviews[i];
        [aCoder encodeObject:view forKey:[NSString stringWithFormat:@"view%d",i]];
    }
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self=[super init]) {
        self.backgroundColor=[aDecoder decodeObjectForKey:@"backgroundColor"];
        self.image=[aDecoder decodeObjectForKey:@"image"];
        self.contentMode=[aDecoder decodeIntForKey:@"contentMode"];
        int subviewscount=[aDecoder decodeIntForKey:@"subviewscount"];
        for(int i=0;i<subviewscount;i++)
        {
           UIView* view=[aDecoder decodeObjectForKey:[NSString stringWithFormat:@"view%d",i]];
            [self addSubview:view];
        }
    }
    return self;
}
@end

...
lu yuan
  • 7,207
  • 9
  • 44
  • 78

2 Answers2

1

When you instantiate a view object from Nib file iOS will use nib file's XML detail and will create a decoder from it. Then it will call view's initWithCoder: method so that your view can use decoder info to initialise its state and properties.

kkumpavat
  • 452
  • 2
  • 10
  • But I did not import the category, why the method initWithCoder: get called? – lu yuan Jun 13 '14 at 09:22
  • 1
    You need to import category only if you have added new methods, If you try to override standard methods in categories they will be iOS will call method implemented in category instead of calling its framework implementation. – kkumpavat Jun 13 '14 at 09:49
1

You don''t need to import the the categories explicitly unless you are adding a new method to the category and using it in your controller(importing is required since the compiler would know that the method is available). Here what's happening is your Xib may contain an UIImageView, while the Xib is get loaded that image view is created and this will cause the initWithCoder to be called since the object is instantiated from the Xib(This is common for all the objects instantiated from the Xib). No magic is happening here

Anil Varghese
  • 42,757
  • 9
  • 93
  • 110
  • The mechanism of category seems unbelievable. – lu yuan Jun 13 '14 at 09:39
  • Category is used to extend an existing class such as Add/Modify the methods. All the changes are becomes the part the actual class. means if you extend a UIImageView class by altering a an existing method, that change is applicable to all the UIImageView's of your project – Anil Varghese Jun 13 '14 at 09:52
  • I could understand this, but it really makes me feel unsafe without importing it. – lu yuan Jun 13 '14 at 09:54
  • I would suggest you not to use category to override a method unless it is really necessary(applicable to all). You can subclass UIImageView use that class where ever it is required – Anil Varghese Jun 13 '14 at 09:58