指针的自定义对象数组都指向同一对象

时间:2018-07-24 14:10:48

标签: ios objective-c xcode objective-c++

这是我的第一篇文章,很抱歉,如果它太乱了。

我想动态添加在Pixra中创建的自定义对象NSMutableArray。因为它使用接口,所以我用指针来实例化对象:Pixra* pix = [Pixra alloc];

当我解析数组时,我可以看到我添加的所有指针都指向同一对象,因为属性quality的值对于数组的所有元素都是相同的。这是我在数组中添加元素的循环实现。

NSMutableArray* imagesRaw = [NSMutableArray array];
double j=0.0;
for (UIImage* img in images){
  Pixra* pix = [Pixra alloc];
  [pix setMatrix:img];
  [pix setQuality:j];
  [imagesRaw addObject:pix];
  cout << [imagesRaw[0] getQuality] << "\n";
  j++;
} 

控制台日志显示质量正在迭代,而不应该重复,因为我只显示数组的第一个元素。

Pixra.mm

#import <Foundation/Foundation.h>
#import "Pixra.h"
@implementation Pixra

UIImage* matrix;
double quality;

-(void) setMatrix:(UIImage*)matrixArg{
  matrix = matrixArg;
}
-(UIImage*) getMatrix{
  return matrix;
}
-(void) setQuality:(double)qualityArg{
  quality = qualityArg;
}
-(double) getQuality{
  return quality;
}
-(id) pixraInit:(UIImage*)img:(double)quality{
  self = [super init];
  self.matrix = img;
  self.quality = quality;
  return self;
}
+(instancetype) pixraInit:(UIImage*)img:(double)quality{
  Pixra* pix = [[Pixra alloc] pixraInit:img :quality];
  return pix;
}
@end

Pixra.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class Pixra;
@interface Pixra : NSObject
-(void) setMatrix:(UIImage*)matrixArg;
-(UIImage*) getMatrix;
-(void) setQuality:(double)qualityArg;
-(double) getQuality;
+(instancetype) pixraInit:(UIImage*)img :(double)quality;
@end

如您所见,我尝试使用返回实例的initalizer来执行此操作,但是它也不起作用。 如何在自定义对象的不同实例上创建指针?

2 个答案:

答案 0 :(得分:3)

当您这样编写类实现文件时,编译器会将其用作全局变量。每个内存块只有一个内存块。

UIImage* matrix;
double quality;

有了这些 properties ,所有Pixra对象实例都使用全局变量来保存它们,通常用于Sington Instance设计模式中。

那么如何纠正呢?如果您正在寻找正确的属性来为每个matrix实例保存qualityPixra值,请像这样使用@property

@interface Pixra : NSObject

@property (strong) UIImage *matrix;
@property (assign) CGFloat quality;

@end

请注意,此属性实现涵盖了setMatrixmatrix属性方法。在Google中查看有关Objective-C Class Property的更多详细信息。

答案 1 :(得分:1)

您忘记了init

Pixra* pix = [Pixra alloc];

摘自NSObject's init() method的文档:

  

在初始化之前,对象无法使用。

     

在某些情况下,init()方法的自定义实现可能会返回替代对象。 因此,在后续代码中,必须始终使用init()返回的对象,而不是alloc或allocWithZone返回的对象:

因此替换

Pixra* pix = [Pixra alloc];

Pixra* pix = [[Pixra alloc] init];

Pixra* pix = [Pixra new];