我正在处理一些释放问题,也许还有无法弄清楚的强引用或循环引用。我有 3 个UIView实例化,如下所示:
ViewController我在故事板中添加了一个主要内容,UIView并且在类中UIView有一个出口,例如:weak
class ViewController : UIViewController {
//MARK: - outlets
@IBOutlet weak var firstView: FirstUiview!
}
Run Code Online (Sandbox Code Playgroud)
第二个UIView作为子视图以编程方式添加到第一个视图,如下所示:
class FirstUiview : UIView {
//creating an instance of secondUiView
lazy var mySecondView: SecondViewClass = {
let dv = SecondViewClass()
dv.backgroundColor = UIColor.red
return dv
}()
//sometime later by clicking on a button
self.addSubview(mySecondView)
//a button will be tapped to remove mySecondView;
//later will be called at some point upon tapping: …Run Code Online (Sandbox Code Playgroud) 我有一个带NSTimer *myTimer;变量的类.在某些时候我做:
myTimer = [NSTimer scheduledTimerWithTimeInterval:20 target:self selector:@selector(doStuff) userInfo:nil repeats: YES];
Run Code Online (Sandbox Code Playgroud)
另外,我有一个方法:
- (void)doStuff
{
if(myTimer)
{
//do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
当课程通过以下方式发布时,我会停止计时器:
- (void)dealloc
{
if (myTimer) { //if myTimer==nil it already has been stopped in the same way
[myTimer invalidate];
myTimer = nil;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,问题在于,当我释放课程时,计时器继续开启和开启事件.难道我做错了什么?似乎从不调用dealloc方法,否则myTimer将为nil,即使选择器被触发,它也不会进入if(myTimer)
我在我的一个视图控制器的loadView:方法中遇到了一些代码问题.基本上我有一个视图,它在一个更大的视图中(在iPad上),并有一些标签,按钮和图标,以编程方式加载到它.
当视图控制器调用dealloc方法并尝试释放时,会发生此问题.我得到了一个- [CALayer发布]:发送到解除分配的实例错误的消息,应用程序崩溃了.
从阅读有关此错误的内容来看,我似乎过度发布了一些内容,但我认为不是这样的:下面的代码是麻烦制造者,我已经尝试了对所有内容的自动释放和手动释放调用,以及根本不释放它们(我知道,我知道,这很糟糕)但它继续造成havok.
container = [[UIView alloc] initWithFrame:CGRectNull];
container.autoresizingMask = ( UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin );
container.frame = CGRectMake( (viewSize.width-320)/2, (viewSize.height-480)/2, 320, 480);
[self.view addSubview:container];
UILabel *welcomeTo = [[[UILabel alloc] initWithFrame:CGRectNull] autorelease];
welcomeTo.backgroundColor = [UIColor clearColor];
welcomeTo.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:18.0];
welcomeTo.frame = CGRectMake(23, 15, 103, 24);
welcomeTo.shadowColor = [UIColor blackColor];
welcomeTo.shadowOffset = CGSizeMake( 0, 1 );
welcomeTo.text = @"Welcome to";
welcomeTo.textAlignment = UITextAlignmentLeft;
welcomeTo.textColor = [UIColor colorWithWhite:1.0 alpha:0.6];
[container addSubview:welcomeTo];
UILabel …Run Code Online (Sandbox Code Playgroud) 我想理解为什么这样做会很有用(假设先前已经分配了"对象"):
[object release];
object=nil;
Run Code Online (Sandbox Code Playgroud)
感谢帮助,
斯特凡
-(IBAction)voiceBroadcast
{
if ([audioPlayer isPlaying]) {
[audioPlayer stop];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
else {
if (nil != audioPlayer) {
[audioPlayer play];
audioPlayer.volume = 0.0;
[self performSelector:@selector(doBgMusicFadeIn)];
[self performSelector:@selector(doBgMusicFadeDown) withObject:nil afterDelay:3];
[self performSelector:@selector(startVoiceBroadcast) withObject:nil afterDelay:4];
}
}
}
-(void)dealloc
{
//position
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
将cancelPreviousPerformRequestsWithTarget:self在dealloc叫,但不工作时,选择仍可以调用.但是,cancelPreviousPerformRequestsWithTarget:self在voiceBroadcast没有问题.该cancelPreviousPerformRequestsWithTarget方法不能用于dealloc?
添加和删除观察者的最佳做法是NSNotificationCenter什么?
我想知道如果加入self作为观察员viewDidLoad和删除self的viewDidUnload就足够了.也许我应该删除self的dealloc为好.
也许需要考虑低内存条件.我可以看到添加viewDidLoad和删除dealloc有问题:viewDidUnload由于内存不足而被调用...然后viewDidLoad在再次显示视图时被调用...现在self已被添加为观察者两次没有删除(因为dealloc不是所谓的).
注意:我正在考虑一个self引用UIViewController子类的基本示例.
似乎在Objective-C中,负责内存分配的方法(如malloc()在C中),是-[NSObject alloc].那释放那些记忆怎么样?这样做了-[NSObject dealloc]吗?这就是为什么在我们自己的班级里dealloc,我们必须打电话给[super dealloc]最后一个而不是第一个?
我问,因为我不明白为什么,如果我[super dealloc]先放,并[_bar release]在下一行使用释放对象,我不会得到分段错误.之后[super dealloc]运行,如果它释放对象的内存,_bar应该已经不属于该进程的内存块.
有人可以告诉我如果覆盖Objective-C中的dealloc方法会发生什么?因为它会崩溃或者只是开始泄漏记忆.我一直想知道会发生什么以及为什么有必要阻止程序员直接使用dealloc.
在什么情况下你会不得不做这样的事情?
编辑:对不起家伙不清楚.我主要用语言或ARC类型编码.
鉴于以下简单实现:
@implementation RTUDeallocLogger
-(void)dealloc
{
NSLog(@"deallocated");
}
@end
Run Code Online (Sandbox Code Playgroud)
我们在ARC下运行以下代码:
@implementation RTURunner
{
NSArray* arr;
}
-(void)run{
arr = [NSArray
arrayWithObjects:[[RTUDeallocLogger alloc]init],
[[RTUDeallocLogger alloc]init],
[[RTUDeallocLogger alloc]init],
nil];
NSLog(@"nulling arr");
arr = NULL;
NSLog(@"finished nulling");
}
@end
Run Code Online (Sandbox Code Playgroud)
我们得到以下日志输出:
nulling arr finished nulling deallocated deallocated deallocated
所有解除分配完成后我想执行一个动作.这可能吗?
这个问题的目的是为了更多地了解ARC的机制,特别是ARC在什么时候触发这些解除分配,以及当我删除引用时这是否会同步发生.
我在Windows7上使用Qt5,我最近发现了一个有趣的Qt示例代码.
基本上,它看起来像这样:
ButtonWidget::ButtonWidget(const QStringList &texts, QWidget * parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout * gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i)
{
QPushButton * button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(QString)), this, SIGNAL(clicked(QString)));
setLayout(gridLayout);
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好且有用的示例,但它没有正确的析构函数...以防万一我要删除ButtonWidget类型的对象,或者我想自定义代码以便能够删除/添加小部件.这个想法是如何删除在构造函数中创建的所有对象(动态地,使用new).
我的方法是使用私有变量QList<QPushButton*> list,将所有新分配的按钮添加到列表中(在构造函数中),并使用上面的方法在析构函数中逐个删除它们list.但这似乎是幼儿园的方法.
我认为必须有其他方式,更好的方法来做到这一点,没有列表,没有搞乱构造函数代码:)感谢您的时间和耐心!
dealloc ×10
ios ×4
iphone ×4
objective-c ×4
c++ ×1
calayer ×1
cocoa ×1
destructor ×1
dynamic ×1
invalidation ×1
ios4 ×1
nstimer ×1
nszombie ×1
qt ×1
selector ×1
swift ×1
viewdidload ×1