标签: dealloc

自定义dealloc和ARC(Objective-C)

在我的小iPad应用程序中,我有一个使用观察者的"切换语言"功能.每个视图控制器在其期间向我的观察者注册viewDidLoad:.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [observer registerObject:self];
}
Run Code Online (Sandbox Code Playgroud)

当用户点击"更改语言"按钮时,新语言将存储在我的模型中,并通知观察者并updateUi:在其注册对象上调用选择器.

这非常有效,除了我在TabBarController中有视图控制器.这是因为当标签栏加载时,它会从其子控制器中获取选项卡图标而不初始化视图,因此viewDidLoad:不会调用,因此这些视图控制器不会收到语言更改通知.因此,我将registerObject:调用移到了init方法中.

回来我viewDidLoad:以前和我的观察员一起注册时,我常常viewDidUnload:取消注册.由于我现在正在注册init,因此取消注册是很有意义的dealloc.

但这是我的问题.我写的时候:

- (void) dealloc
{
    [observer unregisterObject:self];
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

ARC禁止发送'dealloc'的显式消息

因为我需要打电话[super dealloc]来确保超级班级正常清理,但ARC禁止这样做,我现在卡住了.当我的物体死亡时,还有另一种获取信息的方法吗?

xcode objective-c dealloc ios automatic-ref-counting

207
推荐指数
1
解决办法
7万
查看次数

斯威夫特的dealloc

我想在视图控制器的生命周期结束时执行一些清理,即删除NSNotificationCenter通知.dealloc在Swift编译器错误中实现结果:

Cannot override 'dealloc' which has been marked unavailable
Run Code Online (Sandbox Code Playgroud)

在Swift中对象生命结束时执行某些清理的首选方法是什么?

dealloc swift

141
推荐指数
3
解决办法
6万
查看次数

在init和dealloc方法中有效使用访问器?

我现在从几个来源(stackoverflow.com,cocoa-dev,文档,博客等)中听到,在init和dealloc方法中使用访问器和设置(foo,setFoo :)是"错误的".据我所知,如果你这样做,很可能会混淆其他正在观察财产的物体.(这里给出一个简单的例子)

但是,由于以下原因,我不得不说我不同意这种做法:

新的Objective-C运行时(iPhone上的那个和10.5中的64位运行时)允许您在声明相应的ivar的情况下声明属性.例如,以下类将在10.5或iPhone(设备,而不是模拟器)上编译得很好:

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end
Run Code Online (Sandbox Code Playgroud)

理解上面是一个完全有效的Objective-C类,假设我决定编写一个初始化程序,并且出于内存管理的目的,使用dealloc方法(因为在iPhone上没有GC).我读过有关初始化器和释放器的所有内容都会让我编写以下两种方法:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

但是,根据文件和流行的观点,这是"错误的".所以我的问题是这样的:

  1. 如何在不使用访问器的情况下初始化someObject?您可能会说编译器(或运行时或其他)将确保someObject已设置为nil,但我相信依赖它会是不正确的行为.在C语言中有一个不错的背景,由于没有正确初始化变量,我看到了相当数量的错误,这似乎没有什么不同.
  2. 如果我不应该在dealloc方法中使用访问器,我该如何释放someObject?

如果其中任何一个的答案是"你不能",那么在init和dealloc方法中使用访问器怎么可能不好?

initialization properties objective-c accessor dealloc

24
推荐指数
2
解决办法
5180
查看次数

iPhone - dealloc - 发布与零

想知道有经验的人是否可以解释这一点.我见过......的例子

  [view release];

  view = nil;  
Run Code Online (Sandbox Code Playgroud)

....在(void)dealloc里面.

有什么区别,哪一个比另一个更好?什么是最好的方法?

在进行retainCount测试时,我个人已经看到nil为我减少了3到0的计数,但是只发布从3减少到2.

memory iphone memory-management release-management dealloc

24
推荐指数
2
解决办法
1万
查看次数

23
推荐指数
3
解决办法
9932
查看次数

为什么将正在进行释放的对象设置为弱属性会导致崩溃

Clang的Objective-C自动参考计数中,我们看到以下内容

对于__weak对象,左值更新为指向新的指针,除非新指针是当前正在进行解除分配的对象,在这种情况下,左值更新为空指针.这必须相对于对象的其他赋值,从对象读取以及新指针的最终版本以原子方式执行.

objc-weak.mm中,我们看到以下代码块weak_register_no_lock():

    if (deallocating) {
    if (crashIfDeallocating) {
        _objc_fatal("Cannot form weak reference to instance (%p) of "
                    "class %s. It is possible that this object was "
                    "over-released, or is in the process of deallocation.",
                    (void*)referent, object_getClassName((id)referent));
    } else {
        return nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的UIViewController子类dealloc方法中设置了一个断点,并尝试[self allowsWeakReference]在lldb中调用,从而产生了NO值.

如果我们尝试将self设置为另一个对象的weak属性,则应用程序将根据objc-weak.mm代码崩溃.

问题是 - 为什么会发生这种情况?铿锵的规格是错的吗?这是objc实现中的一个错误吗?


这是一段简单的代码,可以重现崩溃:

//cc -fmodules -fobjc-arc -g crash.m -o crash
@import Foundation;

@interface Foo : NSObject
@end

@implementation Foo …
Run Code Online (Sandbox Code Playgroud)

weak-references objective-c clang dealloc automatic-ref-counting

21
推荐指数
1
解决办法
1627
查看次数

初始化属性,点符号

在我的init方法中使用点表示法将retain属性初始化为nil是不是一个坏主意?

对于像这样的普通房产:

@property (nonatomic, retain) id foo;
Run Code Online (Sandbox Code Playgroud)

在我设置的init方法中说self.foo = nil.合成的方法首先释放或自动释放foo(不完全确定潜在的实施).被fooguaranted第一setter或getter调用之前是零?或者它会指向随机垃圾,除非我明确设置foo = nil没有点符号?

initialization properties reference-counting objective-c dealloc

20
推荐指数
1
解决办法
1万
查看次数

UIPopoverController dealloc被称为ARC环境

在第二次显示弹出控制器时(在解除它然后重新显示它之后),我收到以下错误:

因未捕获的异常'NSGenericException'而终止应用程序,原因:' - [UIPopoverController dealloc]到达,而popover仍然可见.

堆栈跟踪只是一堆十六进制,SIGABRT每次都发生在UIApplicationMain.这是按钮触发的代码:

- (IBAction)createNewScore:(id)sender {
    if (self.pc)
        if (self.pc.popoverVisible)
            return;
        else
        // Breakpoint is hit here—crashes after this line
            [self.pc presentPopoverFromBarButtonItem:(UIBarButtonItem *)sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    NGDocumentInfoViewController *documentInfoVC = [[NGDocumentInfoViewController alloc] initWithBlankDocumentTargetInManagedObjectContext:self.context];
    UINavigationController *navc = [[UINavigationController alloc] initWithRootViewController:documentInfoVC];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneCreatingNewScore:)];
    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelCreatingNewScore:)];
    navc.navigationBar.topItem.leftBarButtonItem = doneButton;
    navc.navigationBar.topItem.rightBarButtonItem = cancelButton;
    CGSize popoverSize = CGSizeMake(documentInfoVC.view.bounds.size.width, documentInfoVC.view.bounds.size.height);
    documentInfoVC.contentSizeForViewInPopover = popoverSize;
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navc];
    popover.delegate = self;
    self.pc …
Run Code Online (Sandbox Code Playgroud)

memory-management dealloc uipopovercontroller ios automatic-ref-counting

19
推荐指数
1
解决办法
8965
查看次数

在UIViewController中添加和删除NSNotificationCenter的观察者

查看各种Apple示例(例如" 添加音乐"),其中我看到它们将观察者添加到默认值NSNotificationCenterviewDidLoad,然后将其删除dealloc.这看起来很危险,viewDidLoad可以多次dealloc调用而不需要调用.然后,这将多次添加相同的观察者,导致多次调用处理程序.

解决这个问题的方法是删除观察者viewDidUnload,但这意味着同一个观察者可能会被移除第二次,dealloc这似乎是一个潜在的问题.

我错过了什么?

objective-c addobserver dealloc nsnotificationcenter ios

17
推荐指数
1
解决办法
2万
查看次数

如果一个函数返回一个UnsafeMutablePointer,我们有责任销毁和释放吗?

例如,如果我要编写此代码:

var t = time_t()
time(&t)
let x = localtime(&t) // returns UnsafeMutablePointer<tm>

println("\(x.memory.tm_hour): \(x.memory.tm_min): \(x.memory.tm_sec)")
Run Code Online (Sandbox Code Playgroud)

......是否还需要做以下事情?

x.destroy()
x.dealloc(1)
Run Code Online (Sandbox Code Playgroud)

或者我们没有分配内存,因此不需要解雇它?


更新#1:

如果我们想象一个函数返回一个UnsafeMutablePointer:

func point() -> UnsafeMutablePointer<String> {
    let a = UnsafeMutablePointer<String>.alloc(1)
    a.initialize("Hello, world!")
    return a
}
Run Code Online (Sandbox Code Playgroud)

调用此函数将导致指向一个永远不会被销毁的对象的指针,除非我们自己做脏工作.

我在这里问的问题是:从一个localtime()呼叫收到的指针有什么不同吗?
模拟器和操场都使我们能够向dealloc(1)返回的指针发送一个调用,但是我们应该这样做还是稍后通过其他方法对返回的指针进行解除分配?

目前我错误地认为我们确实需要销毁和释放.

更新#1.1:

最后的假设是错误的.我不需要发布,因为我没有创建对象.


更新#2:

我在Apple dev论坛上收到了相同查询的一些答案.

一般来说,你的问题的答案是肯定的.如果你收到一个指向你将负责在C中释放的内存的指针,那么你仍然有责任在从swift调用时释放它... [但]在这种特殊情况下你不需要做任何事情.(JQ)

例程本身为结果维护静态内存,您不需要释放它们.(如果你这样做可能会是一件"坏事")...一般来说,你不知道是否需要释放UnsafePointer所指向的东西....它取决于指针获取其值的位置.(ST)

UnsafePointer的dealloc()与free()不兼容.将alloc()与dealloc()和malloc和co配对.用free().如前所述,您正在调用的函数应该告诉您是否是您对释放结果的响应...只有在指针引用的内存中有非平凡的内容*时才需要destroy(),例如强引用或Swift结构或枚举.一般来说,如果它来自C,你可能不需要销毁()它.(事实上​​,你可能不应该销毁()它,因为它没有被Swift初始化.)......*"非平凡的内容"并不是官方的Swift术语.我正在使用类比C++概念"平凡可复制"(虽然不一定是"微不足道").(STE)


最后更新:

我现在写了一篇博客文章,概述了关于发布不安全指针的发现和假设,这些指针从StackOverflow,Apple Dev论坛,Twitter和Apple关于分配内存和释放它的旧文档(ARC之前)获取信息.看到这里.

allocation unsafe-pointers dealloc destroy swift

16
推荐指数
1
解决办法
5101
查看次数